现在的位置: 首页 > 综合 > 正文

设计模式–工厂模式

2018年03月29日 ⁄ 综合 ⁄ 共 2338字 ⁄ 字号 评论关闭

2015年1月25日00:18:40

之前在看JEE的时候就有遇到了工厂模式,不过没有像现在在head first上看到的这么全面,这里我就照着目前的理解来阐述一下工厂模式

工厂模式的核心是把对象的生成与对象的使用隔离出来,这样的隔离存在几个原因,1对象的生成需要初始化一些条件,如初始化一些参数等,2对象的生成容易发生变化,如我们声明一个coffee对象,初始的时候我们要的是卡布奇诺,但是过几天由于原料缺失,我们需要获取是普通的黑咖啡,3对象根据条件生成,条件可能发生改变或者扩展,如果我们生成面包对象,面包种类可能随时间增多,部分面包可能缺失                           使用的工厂模式可以将这部分容易变化的代码隔离出来,同时解除程序与具体类的耦合。

正如上面这张图,对应于一个实际的例子,比如餐饮软件,我们提供点盖浇饭的服务,盖浇饭有青椒肉丝盖浇饭,番茄炒蛋盖浇饭,鱼香肉丝盖浇饭。程序根据用户选择来提供准备,配送和结账的方法。

使用工厂模式,我们可以定义一个盖浇饭的接口,接口中定义这样三个方法,然后让三种盖浇饭分别实现接口,在我们的程序各个需要用到的部分我们可能需要根据用户选择生成盖浇饭对象,然后执行相应的操作,最后得到的依赖关系就如同左图所示,我们需要在每个需要创建盖浇饭的地方插入下面格式的代码

if(condition1){
   A=new A1();
else if(condition2){
  A= new A2();
 else if(condition3){
  A= new A3();
}else{
  A=null;
}

这样存在很多问题,1代码重复冗余,重复冗余就带来了修改困难的问题,比如种类改变或者增减。2耦合性大,每一处子程序都依赖于所有的可能出现的具体实现类,这个问题最后会等价于前面的问题

如果我们按照工厂模式修改我们的设计,我定义一个工厂创建我们需要的对象,我们在所有需要生成对象的时候只要添加下列代码就行了

A=factory.createA([CONDITION]);

具体的对象创建交给工厂去做,我们最后得到的依赖关系就是像右图所示。上面的问题基本得到解决,虽然没有完全符合开闭原则(添加新种类的时候可能需要添加促使生成新种类的条件参数)。但是默认创建(不需要参数直接创建对象)和对象的创建过程都是对原程序隐藏的,这解除了程序对具体类的依赖 (所以工厂模式也是一种依赖导致的主要手段)

这里所说的工厂模式是简单工厂模式,这里我们所做的就是单纯把对象的生成与对象的创建隔离开来,接下来我们将讨论工厂模式的其他方式

1工厂方法

工厂方法和简单工厂模式很类似,但是实际上存在很大的区别,

//盖浇饭的英语不知道怎么说 就这么将就着吧
public abstract class canteen{
   public void order();
   public void pay(){....};
   private abstract gaijiaofan   creatgaijiaofan(condition);
}

<pre name="code" class="java">public class  restraurantB extend canteen{
   private gaijiaofan   creatgaijiaofan(condition);
}
public class restraurantA extend canteen{
   private gaijiaofan   creatgaijiaofan(condition){...};
}


上面是一个工厂方法的例子,简单点就是用一个单纯的方法作为对象的生产者,也就是在类中声明一个扮演工厂角色的方法。如果就这么看似乎是和简单工厂模式是没有区别,但是工厂方法的运用的常用情形是我们需要根据条件来区分工厂方法的执行 ,比如像上面的例子,我们有一家餐厅,他有A和B2个分店,根据分店不同,他们生产者不同的盖浇饭,一家卖鱼香肉丝,一家卖青椒肉丝,  或者两家都卖这两种盖浇饭,但是B工厂做的比A工厂要更加辣点。

工厂方法实现的效果是让子类决定生成对象的类型(你选择的子类选择了你能生产的对象的产品族,然后在子类中通过执行工厂作用的方法生成对象),其实我认为这个功能不套上一层工厂就没有没什么意义,然而套上一层工厂之后就和抽象工厂的方式没有区别。那么接下来就讨论抽象工厂模式。

2抽象工厂

抽象工厂可以理解工厂的工厂,也就是我们通过一个工厂生产 出一个工厂,然后通过生产出的工厂来生产产品对象。

举个例子说明 一个电脑公司拥有2种主打品牌的电脑,A类电脑和B类电脑,随着技术进步,电脑公司推出了2代产品,也就是A2代和B2代

public interface factory{
   public A getA();
   public B getB();
}

//生产1代产品
public class Produce1 implements factory{
  
}

<pre name="code" class="java">//生产2代产品
public class Produce2 implements factory{
  
}

//生产工厂
public class ProduceFactory{
  public factory getFactory(...);
}


抽象工厂的代码就像上面的一样,我们通过工厂的工厂 拿到工厂,然后通过工厂拿到具体的产品。

从抽象一点的角度来看抽象工厂模式就是抽象工厂是实现一种以多维的方式来看待对象的生产问题,在简单工厂模式里面,我们用条件变量作为维度来看待对象的实现问题(对象根据条件选择来生成),在抽象工厂中我们以2维或者跟高维度来看待对象生产问题,我们根据1个或者多个条件拿到工厂,工厂再去生产具体的产品,选择工厂的条件也是产品的维度。

时间不早了今天就到这里了

抱歉!评论已关闭.