设计模式——工厂方法模式和简单工厂模式

概念

工厂设计模式是一种创建型模式,它提供了一种创建对象的最佳方式。

在工厂模式中,我们创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

简单工厂模式是工场方法模式的一种特例。

关键 工厂返回创建的对象

针对的问题

在面向对象编程中,最常用的方法是new一个操作符产生一个对象实例,new对象操作符就是用来构造对象实例的,但是在一些情况下,new操作符直接生成对象会带来一些问题,举例说,许多类型对象的创建都需要一系列的步骤,可能需要计算或取得对象的初始设置,选择生成哪个子对象实例,或者在生成需要的对象之前必须先生成一些辅助功能的对象,这些情况下,对象的建立就是一个过程,不仅是一个操作

上图就是没有工厂模式时,用户需要自己new一辆车,这样,车和人就耦合在了一起。

那么怎么能够方便的构建对象实例,而不关心构造对象实例的细节和复杂过程呢,那就是建立一个工厂来创建对象。把创建的过程封装到工厂里

分析

工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到灵活性的目的。

工厂模式一共三类

  • 简单工厂模式
  • 工厂方法模式
  • 抽象工厂模式

一般将简单工厂模式看为工厂方法模式的一种特例,二者归为一类。

角色组成(简单工厂模式)

1)工厂类角色:这是本模式的核心,含有一定的商业逻辑和判断逻辑,用来创建产品
2) 抽象产品角色:它一般是具体产品继承的父类或者实现的接口。
3) 具体产品角色:工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现。

举例

1)还没有工厂时代:假如还没有工业革命,如果一个客户要一款宝马车,一般的做法是客户去创建一款宝马车,然后拿来用。
​ 2)简单工厂模式:后来出现工业革命。用户不用去创建宝马车。因为客户有一个工厂来帮他创建宝马.想要什么车,这个工厂就可以建。比如想要320i系列车。工厂就创建这个系列的车。即工厂可以创建产品。
​ 3)工厂方法模式时代:为了满足客户,宝马车系列越来越多,如320i,523i,30li等系列一个工厂无法创建所有的宝马系列。于是由单独分出来多个具体的工厂。每个具体工厂创建一种系列。即具体工厂类只能创建一个具体产品。但是宝马工厂还是个抽象。你需要指定某个具体的工厂才能生产车出来。

4)抽象工厂模式时代:随着客户的要求越来越高,宝马车必须配置空调。于是这个工厂开始生产宝马车和需要的空调。

最终是客户只要对宝马的销售员说:我要523i空调车,销售员就直接给他523i空调车了。而不用自己去创建523i空调车宝马车.

这就是工厂模式。

简单工厂模式

使用简单工厂模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//产品类
abstruct class BMW
{
public BMW(){}
}
public class BMW100 extends BMW
{
public BMW100()
{
System.out.println("this is BMW100");
}
}
public class BMW200 extends BMW
{
public BMW200()
{
System.out.println("this is BMW200");
}
}
1
2
3
4
5
6
7
8
9
10
//工厂类
public class Factory
{
public BMW createBMW(int type)
{
if(type==100) return new BMW100();
if(type==200) return new BMW200();
else return null;
}
}
1
2
3
4
5
6
7
8
9
10
//客户端测试类
public class Customer
{
public static void main(Stringp[] args)
{
Factory factory =new Factory();
BMW bmw100 =factory.createBMW(100);
BMW bmw200 =factory.createBMW(200);
}
}

简单工厂类的缺陷以及工厂方法模式的提出

在简单工厂中,当客户不再满足现有的车型号时,想要一种更快的车,只要这种车满足抽象产品指定的规则,只要通知工厂类增加相应的逻辑就好了,但是每增加一种车,都要在工厂类中增加相应的逻辑,工厂类十分被动,这样的工厂类成为全能类或者上帝类。

实际中,产品可能是一种多层次的树状结构,由于简单工厂模式只有一个工厂类,所以好多代码都放在一个工厂类里

于是提出了工厂方法模式

工厂方法模式概念

工厂方法模式定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类。也就是在所有工厂中抽象出一个接口。当增加功能时,直接增加相应的物品类和工厂类就行了。

工厂方法模式去掉了简单工厂模式中工厂方法的静态属性,使得它可以被子类继承。这样在简单工厂模式里集中在工厂方法上的压力可以由工厂方法模式里不同的工厂子类来分担。 (一个类一个工厂)

角色构成(工厂方法模式)

1)抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。
2)具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。
3)抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。
4)具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。

工厂方法模式使用继承自抽象工厂角色的多个子类来代替简单工厂模式中的上帝类,分担了对象承受的压力。

举例 (工厂方法模式)

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
30
31
32
33
//产品类 四种车,宝马1系,(两种),2系(两种)
abstruct class BMW()
{
public BMW();
}
pubblic class BMW100 extends BMW
{
public BMW100()
{
System.out.println("this is BMW100");
}
}
pubblic class BMW109 extends BMW
{
public BMW109()
{
System.out.println("this is BMW100");
}
}
pubblic class BMW200 extends BMW
{
public BMW200()
{
System.out.println("this is BMW200");
}
}
pubblic class BMW209 extends BMW
{
public BMW209()
{
System.out.println("this is BMW209");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
interface Factory
{
BMW createBMW();
}
public class FactoryBMW1 implements FactoryBMW{

@Override
public BMW100 createBMW() {
return new BMW100();
}

}
public class FactoryBMW2 implements FactoryBMW {
@Override
public BMW200 createBMW() {

return new BMW200();
}
} //分为100的工厂和200的工厂(省略了两个工厂)。都实现了工厂的接口。
1
2
3
4
5
6
7
8
9
//客户端
public class test()
{
public static void main()
{
Factory f =new FactoryBMW1(); // 实例化一个1系工厂。
BMW b = f.createBMW(); //实例化一个100车。
}
}

想加一辆车,就单独加车的类,这个车的工厂,然后只修改客户端的代码即可。

工厂方法模式实现时,客户端需要决定实例化哪一个工厂来创建对象,工厂方法把简单工厂的内部逻辑移到了客户端代码来执行。