工厂模式

简单工厂模式(Simple Factory Pattern)

它由称为静态工厂模式,属于创建型模式,可以根据参数的不同,返回不同类型的实例,它专门定义了一个类,负责创建其他类的实例,被创建的类通常都有共同的父类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Product{
abstract void say(){
printf("I am Product.\n");
}
};
class ConcreteProductA : public Product{
void say(){
printf("I am A.\n");
}
};
class ConcreteProductB: public Product{
void say(){
printf("I am B.\n");
}
};
class Factory{
Product* create(string name){
if(name == "A"){
return new ConcreteProductA();
}
else if(name == "B"){
return new ConcreteProductB();
}
return NULL;
}
};

模式分析

  • 将对象的创建和使用分离,降低耦合度(优点)
  • 如果创建方法为static时,可不创建对象即可调用,只需要传入参数,如果把参数保存在XML等格式的配置文件中,修改参数时刻不改变任何代码(优点)
  • 当增加新的产品时,需要修改逻辑判断,不利于拓展和维护(缺点)
  • 工厂类承担了创建对象的重要角色,一旦不能工作,整个系统将受影响(缺点)

简单的应用

JDK中的java.text.DateFormat

格式化一个本地或者时间

1
2
3
public final static DateFormat getDateInstance();
public final static DateFormat getDateInstance(int stype);
public final static DateFormat getDateInstance(int stype, Locate l);

Java加密技术

1
2
KeyGenerator keyGen=KeyGenerator.getInstance("DESede");
Cipher cp=Cipher.getInstance("DESede");

工厂方法模式(Factory Method Pattern)

它也叫多态工厂模式,在这种模式当中,工厂父类定义创建产品的接口,继承其类的子类负责创建具体的产品,将实例化操作延迟到了工厂子类完成,由子类来决定应该实例化哪个产品。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Factory{
virtual Product* create();
};
class FactoryA: public Factory{
Product* create(){
return new ConcreteProductA();
}
};
class FactoryB : public Factory{
Product* create(){
return new ConcreteProductB();
}
};

模式分析

  • 和简单工厂模式一样,隐藏了具体产品的细节,用户只关心所需产品的对应工厂,而不是细节
  • 相比于简单工厂模式,工厂方法模式在加入新产品时,不需要修改接口和其他产品的工厂类,只需新添加具体工厂的类和实现即可,拓展性增强,符合开闭原则。
  • 客户端拥有的是Factory的接口,由于是多态的,因此客户端不需要知道是哪个子工厂类去创建产品,而时运行时动态绑定对应工厂类。
  • 工厂类的增加使得系统的复杂度提高,有更多的类需要编译和运行,带来了额外的开销

模式应用

JDBC的工厂方法:

1
2
3
Connection conn=DriverManager.getConnection("jdbc:microsoft:sqlserver://localhost:1433; DatabaseName=DB;user=sa;password=");
Statement statement=conn.createStatement();
ResultSet rs=statement.executeQuery("select * from UserInfo");

抽象工厂模式(Abstract Factory)

它提供了一个创建一系列相关或相互依赖的对象的接口,无需指定它们具体的类。在工厂方法模式中,一个工厂只能创建一件具体的产品,有时,我们需要一个工厂可以提供多个产品对象。

产品等级结构:继承机构,如一个抽象类是电视机,子类继承的有海尔电视机,TCL电视机,这些产品构成了产品等级结构

产品族: 同一个工厂生产的,不同等级结构的产品,如海尔电器工厂,生产的海尔电视机,和海尔电冰箱,这两个产品分别位于电冰箱和电视机等级结构中,它们这样同属海尔旗下的不同类型的产品就是一个族。

而抽象工厂模式,就是生产一个产品族的产品,它能够提供生产多个位于不同产品等级结构下属于不同类型的具体产品。

抽象工厂模式VS工厂方法模式

工厂方法模式是生产一个产品等级结构的产品,产品都继承一个公共的接口;而抽象工厂模式需要面对多个不同产品等级的产品族的创建。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class A{}; //abstarct
class B{};//abstract
class a1:public A{};
class a2:public A{};
class b1:public B{};
class b2:public B{};
class factory{
vitrual A* createA(){};
vitrual B* createB(){};
};
class factory1{
A* craeteA(){return new a1();}
B* createB(){return new b1();}
};
class factory2{
A* craeteA(){return new a2();}
B* createB(){return new b2();}
}

模式分析

  • 一个产品族的多个对象被设计在一起工作,使得客户端使用同一个产品族中的对象,比较实用
  • 增加一个新的具体工厂和产品族很方便。
  • 难以拓展新的产品种类,如要工厂1,2都要生产产品C,需要改接口,新增createC();
  • 增加产品等级结构比较麻烦,例如产品A是手机,1表示华为厂商,a1则是华为手机,那么想要表示华为手机中的荣耀和mate手机,改动就比较大。

另外,当抽象工厂模式只生产一种类型的产品,即只有一个create方法,它将变成工厂方法模式。