`
renyanwei
  • 浏览: 70112 次
  • 性别: Icon_minigender_1
  • 来自: 郑州
社区版块
存档分类
最新评论

抽象工厂其实就是这么简单

阅读更多

抽象工厂,是简单工厂的加强版,呵呵,比后者更加抽象化了,不过,的确很好用。

 

抽象工厂可以这么理解,你要到商场里去买衣服,好了,就这么多,就可以是抽象工厂模式,首先,你到商场里去买衣服,但是商场是抽象的,是不存在的,只是一个概念,那么,你要到哪个商场里去买衣服呢? 丹尼斯百货? 恩 这就是实实在在存在的商场了, 呵呵, 再者, 你要去买衣服,衣服也是抽象的,不存在的, 哦,我要去买CK内裤,哦 ,这就是实实在在的的衣服了,所以,这里可以理解为:

商场(抽象工厂)

丹尼斯百货(实体工厂)

衣服(抽象产品)

CK内裤(实体产品)

 

这里我们有一个需求,就是我要从数据库里分别读取学生和教师的姓名。就这么简单,但是,要求能在不同的数据库上移植。好了,我们现在分析,因为我们交给客户的都是直接编译好的class文件,所以,不要说去动源代码,其实我们可以用抽象工厂模式很好的解决这个问题,首先,我们看一个图

 

 

 

创建出抽象产品,就是规定你的实体产品必须实现什么功能,在这里我们只要求实体产品能够给我们提供返回学生或教师的姓名就就可以了

/*
*	定义接口IStudentService
*	
*	规定所以实体产品必须能够返回学员姓名
*/
package MySchool.ISchoolService;

public interface IStudentService
{
	String getStudentName();
}

/*
*	定义接口ITeacherService
*	
*	规定所以实体产品必须能够返回教师姓名
*/
package MySchool.ISchoolService;

public interface ITeacherService
{
	String getTeacherName();
}

 

我们创建出抽象工厂来,就是定义实体工厂都能生产出什么东西来,在这里只要能创建出学生和教师的数据库操作类就可以了

/*
*	抽象工厂类 AbsFactory
*	
*	负责定义实体工厂所必须实现功能
*/
package MySchool.AbsFactory;

import MySchool.ISchoolService;

public abstract AbsFactory  
{
	abstract IStudentService getStudentService();
	abstract ITeacherService getTeacherService();
}
 

 

这样我们就可以创建出实体产品了

 

//
//	Mysql工厂能生产的两种产品
//
package MySchool.MySQLService;

import MySchool.ISchoolService;

public class StudentService implements IStudentService
{
	public String getStudentName()
	{
		return "这里是从Mysql里读取到的学生姓名";
	}
}

package MySchool.MySQLService;

import MySchool.ISchoolService;

public class TeacherService implements ITeacherService
{
	public String getTeacherName()
	{
		return "这里是从Mysql里读取到的教师姓名";
	}
}


//
//	SQL Server工厂能生产的两种产品
//
package MySchool.SQLServerService;

import MySchool.ISchoolService;

public class StudentService implements IStudentService
{
	public String getStudentName()
	{
		return "这里是从SQL Server里读取到的学生姓名";
	}
}
package School.SQLServerService;

import MySchool.ISchoolService;

public class TeacherService implements ITeacherService
{
	public String getTeacherName()
	{
		return "这里是从SQL Server里读取到的教师姓名";
	}
}

 接下来我们创建出各个实体工厂

 

//
//	MySQL实体工厂,能够生产出学生和教师的操作类
//
package MySchool.MySQLFactory

import MySchool.ISchoolService;
import MySchool.AbsFactory;
import MySchool.MySQLService;

public class MySQLFactory extends AbsFactory
{
	public IStudentService getStudentService()
	{
		return new StudentService();
	}
	public ITeacherService getTeacherService()
	{
		return new TeacherService();
	}
}
//
//	SQL Server实体工厂,能够生产出学生和教师的操作类
//
package MySchool.SQLServerFactory

import MySchool.ISchoolService;
import MySchool.AbsFactory;
import MySchool.SQLServerService;

public class SQLServerFactory extends AbsFactory
{
	public IStudentService getStudentService()
	{
		return new StudentService();
	}
	public ITeacherService getTeacherService()
	{
		return new TeacherService();
	}
}

 

既然我们能够在不改动代码的情况下移植数据库,那么我们就可以利用JAVA的反射技术来读取XML配置文件来动态改变访问具体数据库,我们来改写抽象工厂代码:

/*
*	抽象工厂类 AbsFactory
*	
*	负责定义实体工厂所必须实现功能
*/
package MySchool.AbsFactory;

import MySchool.ISchoolService;
import MySchool.SQLServerFactory;
import MySchool.MySQLFactory;

public abstract AbsFactory  
{
	AbsFactory _factory=null;
	public static absFactory getFactory()
	{
		//这里是读取XML和反射阶段,反射等以后再说,现在先假定是MySQL
              //根据里氏替换原则
		_factory=new MySQLFactory();
		return _factory;
	}
	abstract IStudentService getStudentService();
	abstract ITeacherService getTeacherService();
}

 好了,现在我们再在业务逻辑层来调用查询学员或教师姓名的时候就可以这样来写,这里也用到了里氏替换原则

package MySchool.ShoolManager;

import MySchool.AbsFactory;
import MySchool.ISchoolService;

public class StudentManager  
{
	public String getStudentName()
	{
		IStudentService stuservice=AbsFactory.getFactory().getStudentService();
		String name=stuservice.getStudentName();
		return name;
	}
	
}

 这样 只需要配置XML就可以实现移植数据库功能了,当然,抽象工厂设计模式的应用绝非仅限于此,能不能把它玩转,就靠我们的造化了, 呵呵  还是 那样。 如果有错误的话还是请帮忙指出来, 其实模式是非常灵活的,没必要死板硬套,只要有那么点儿意思就可以了  O(∩_∩)O哈哈~

声明一点儿,代码是我用EditPus顺手捏来的,懒得动MyEclipse了,写出来只是作自己存起来日后看的,有个分号没加啊什么的就见谅了

6
1
分享到:
评论
6 楼 huyuhong001 2008-10-24  
[/align][/color]
引用
[color=orange]
引用
[/size][size=medium][align=center]
  • 你那图是用什么工具画出来的?我也好想画这种图,但是不知道用什么工具,谢谢!
引用
[/i][b][/b][i][/color][color=red][size=small][/size][align=center][/align]
[img][/img][/url][flash=200,200]" wmode="" quality="high" menu="false" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" width="200" height="200">[url][img][/img]
5 楼 lkjust08 2008-10-24  
LZ能力不错,理解的很好,向你学习呀
4 楼 utyphoon 2008-10-24  
不错不错,收藏
3 楼 pignut_wang 2008-10-23  
http://pignut-wang.iteye.com/blog/254676

看看这本书,简直是学习设计模式的终极武器,图文结合,一看就懂
2 楼 niunan 2008-10-23  
学习了。。。。我也想知道那个图是怎么画出来的?
1 楼 WaterSugar 2008-10-23  

顺便弱弱的问一下,你那图是用什么工具画出来的?我也好想画这种图,但是不知道用什么工具,谢谢!

相关推荐

    抽象工厂模式(Abstract Factory Pattern)

    理解头绪,然后接合简单工厂模式、工厂方法模式对工厂家族的了解,再加上抽象工厂模式的意图,头脑中差不多有一个雏型了吧。好了,咱们一起来分析一下。。 先把各个角色揪出来。 抽象工厂:虚拟的衣柜,它只是个概念...

    Java设计模式

    创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。 结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。 行为型模式,共十一种:...

    Java设计模式:工厂模式——图文+代码示例(通俗易懂)

    工厂模式最主要解决的问题就是创建者和调用者的耦合,那么代码层面其实就是取消对new的使用。 工厂模式有三种: 1. 简单工厂模式 2. 工厂方法模式 3. 抽象方法模式 先来看看,简单工厂模式——也叫静态工厂模式,...

    从实例谈面向对象编程、工厂模式和重构

    么还要那么麻烦去请动抽象工厂模式,来生成两类产品呢? 可能还会有人问,即使你使用这种方式,那么在判断具体创建哪个工厂的时候,不是也要用到 switch 语 句吗?我承认这种看法是对的。不过使用工厂模式,其直接...

    深入c#工厂模式的详解

    工厂模式其实就是抽象出一个工厂,我需要什么手机,去哪个工厂买就行了。我不必关心他的制作过程,你只要能生产我要的功能的手机就行。所以我们需要引入简单工厂,让我们不用再关心手机怎么生产的,具体代码的实现见...

    简单过过Javascript设计模式(上)

    最简单的设计模式,其实就是我们常见的: function User(name, age) { this.name = name; this.age = age } let a = new User('asen', 12) 在使用构造器模式的时候,我们本质上是去抽象了每个对象实例的变与不变...

    二十三种设计模式【PDF版】

    设计模式之 Factory(工厂方法和抽象工厂) 使用工厂模式就象使用 new 一样频繁. 设计模式之 Builder 汽车由车轮 方向盘 发动机很多部件组成,同时,将这些部件组装成汽车也是一件复杂的工作,Builder 模式就是将这...

    java与模式源码-DesignPatterns:java设计模式与

    抽象工厂模式 抽象⼯厂是一个中心⼯厂,创建其他⼯厂的模式。 抽象⼯厂模式,所要解决的问题就是在⼀个产品族,存在多个不同类型的产品(Redis集群、操作系 统)情况下,接⼝选择的问题。⽽这种场景在业务开发中也是⾮...

    JAVA核心技术

    这本书讲了23种主要的模式,包括:抽象工厂、适配器、外观模式等。??还有其他的很多模式,估计有100多种。??软件设计模式太多,就我的理解简单说一下最常见的MVC模式。??MVC模式是1996年由Buschmann提出的:??模型...

    《Android应用开发》个人总结报告.doc

    一个是每一行的样式,称作Row Layout,其实就是一个普通的Layout的XML文件。还有就是一个列和现实控件的对应关系 。那个控件显示哪个列的值,这是需要配置的。为了定制一个良好的数据显示控件,最 简单你可以定制很...

    Spring.net框架

    解决这个问题的办法就是“针对抽象(接口)”编程 (依赖倒置原则)。这里的抽象既包括抽象类也包括接口。我不想过多的去谈抽象类和接口的区别,在后续的例子中我们将使用接口。由于接口在进行“动态代理” 时仍能...

    java 面试题 总结

    抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节。抽象包括两个方面,一是过程抽象,二是数据抽象。...

    超级有影响力霸气的Java面试题大全文档

    1.抽象: 抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节。抽象包括两个方面,一是过程抽象,二是...

    是男人就下100层游戏

    项目介绍这毕竟是个小游戏,本身其实没有什么技术难点,主要在于项目的设计,分为如下几个小模块1、玩家 (Player)玩家类我用了单例模式,继承自CCSprite,因为贯穿游戏一直会有玩家存在,在这个版本里也不会有第二个...

    ssh(structs,spring,hibernate)框架中的上传下载

     我们前面已经指出Oracle的Lob字段和一般类型的字段在操作上有一个明显的区别--那就是你必须首先通过Oracle的empty_blob()/empty_clob()初始化Lob字段,然后获取该字段的引用,通过这个引用更改其值。所以要完成对...

Global site tag (gtag.js) - Google Analytics