工厂模式(Factory)

一、工厂模式介绍:

工厂模式实现了创建者和调用者的分离

工厂模式分类:

1.简单工厂模式

2.工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类

​3.抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

面向对象设计的基本原则:

OCP(开闭原则,Open-Closed Principle):

        一个软件的实体应当对扩展开放,对修改关闭。也就是说如果你要对一个已存在的系统做扩展的时候尽量要新增加类,而不是在原有的基础上修改。

DIP(依赖倒转原则,Dependence Inversion Principle)

       针对接口编程,不要针对实现编程。

LoD(迪米特法则,Law Of Demeter)

       只与你直接的朋友通信,而避免和陌生人通信。一个类尽量少的依赖其他类

 

二、工厂模式代码实现

未使用工厂模式的情况

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
//汽车接口
public interface Car {
    void run();
}
//奥迪
public class Audi implements Car { 
    @Override
    public void run() {
        System.out.println("奥迪在跑");
    }
}
//比亚迪
public class Byd implements Car {
    @Override
    public void run() {
        System.out.println("比亚迪在跑。");
    }
}
//汽车测试类
public class TestCar {//调用者
    public static void main(String[] args) {
        Car c1 = new Byd();
        Car c2 = new Audi();    
        c1.run();
        c2.run();
        //未使用工厂模式的时候,调用者会依赖很多类。违反了开闭原则
    }
}

1、简单工厂模式:虽然能通过工厂来创建对象,但是违反了开闭原则。一旦增加功能需要在原有基础上修改代码。

使用了简单工厂模式后:可以创建一个工厂类,该类中提供一个创建汽车的工厂(方法)

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
//汽车工厂
public class CarFactory {
    /**
     * 创建汽车
     * @param type
     * @return
     */
    public static Car createCar(String type){
        //该方法还会有问题,假如以后有很多汽车都需要工厂来创建。则又得修改源代码,违反了OCP开闭原则
        if ("audi".equals(type)) {
            return new Audi();
        }else if ("byd".equals(type)) {
            return new Byd();
        }else{
            return null;
        }
    }
}
//测试简单工厂方法
public class TestSimpleFactoryCar {//调用者
    public static void main(String[] args) {
        //创建汽车
        Car audi = CarFactory.createCar("audi");//创建者
        Car byd = CarFactory.createCar("byd");
        audi.run();
        byd.run();
    }
}

2、工厂方法模式:将工厂类调整为工厂接口,需要什么类型的工厂就使用该类实现该工厂,创建相应的产品。

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
34
//工厂接口
public interface CarFactory {
    //创建汽车方法
    Car createCar();
}
//创建比亚迪汽车的工厂
public class BydFactory implements CarFactory{
    @Override
    public Car createCar() {
        return new Byd();
    }
}
//创建奥迪的工厂
public class AudiFactory implements CarFactory {
    @Override
    public Car createCar() {
        return new Audi();
    }
}
 
//测试工厂方法
public class TestFactoryMethod {
    public static void main(String[] args) {
        /**
         * 工厂方法模式好处在于,以后如果再增加一辆车。只需再实现CarFactory接口即可。避免了OCP开闭原则
         * 不用在原来的代码上修改,只需新增类即可。
         * 例如:增加一辆奔驰,增加一个奔驰工厂BenzFactory即可。更好扩展
         */
        Car audi = new AudiFactory().createCar();
        Car byd = new BydFactory().createCar();
        audi.run();
        byd.run();
    }
}

3、抽象工厂模式:抽象工厂模式用来生产不同产品族的全部产品,对于只增加产品某一部分则不适用。抽象工厂模式是工厂模式的一种升级版本。

在有多个业务品种,业务分类时,抽象工厂能产品不同类别的一个全部产品。例如:生产汽车,抽象工厂模式可以生产高端汽车全部配件来组成一个高端汽车,

低端汽车全部配件来组成要给低端的汽车,但是不能产生一个高端的发动机和一个低端的座椅来组成一个中等的汽车。这样会混乱。

代码实现:

首先使用一个接口来定义一个发动机,使用具体的类来定义发动机的好坏(具体实现)

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
/**
 * 发动机接口
 */
public interface Engine {
    void run();
    void start();
}
//好的发动机
class LuxuryEngine implements Engine{
    @Override
    public void run() {
        System.out.println("好发动机转的快");
    }
    @Override
    public void start() {
        System.out.println("启动快,自动启停");
    }
}
//差的发动机
class LowEngine implements Engine{
    @Override
    public void run() {
        System.out.println("转的慢");
    }
    @Override
    public void start() {
        System.out.println("启动慢");
    }
}

定义一个汽车总工厂,用来生产各种类型的汽车。所有的汽车都需要依赖此工厂来生产汽车。

1
2
3
4
5
6
7
8
/**
 *  汽车总工厂,可以创建轮胎,座椅,发动机
 */
public interface CarFactory {
    Engine createEngine();//创建发动机
    Seat createSeat();//创建座椅
    Tyre createTyre();//创建轮胎
}

然后根据生产的不同产品,类创建具体的实现来生产汽车。例如:专门生产高端的汽车,专门生产低端的汽车。都可以用针对CarFactory具体的实现来创建。

高端汽车制造工厂,所有汽车的生产必须依赖汽车总工厂

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
 *  高端汽车制造工厂
 */
public class LuxuryCarFactory implements CarFactory{
    @Override
    public Engine createEngine() {
        return new LuxuryEngine();
    }
    @Override
    public Seat createSeat() {
        return new LuxurySeat();
    }
    @Override
    public Tyre createTyre() {
        return new LuxuryTyre();
    }
}

低端汽车制造工厂,所有汽车的生产必须依赖汽车总工厂

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
 *  低端汽车制造工厂
 */
public class LowCarFactory implements CarFactory{
    @Override
    public Engine createEngine() {
        return new LowEngine();
    }
    @Override
    public Seat createSeat() {
        return new LowSeat();
    }
    @Override
    public Tyre createTyre() {
        return new LowTyre();
    }
}

具体生产汽车的时候就可以根据需要来创建具体的汽车了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static void main(String[] args) {
    //想要好车
    CarFactory factory = new LuxuryCarFactory();
    Engine engine = factory.createEngine();//创建高端发动机
    engine.run();
    engine.start();
     
    //想要差一点的车
    CarFactory factory2 = new LowCarFactory();
    Engine e2= factory2.createEngine();
    Seat s2 = factory2.createSeat();
    Tyre t2 = factory2.createTyre();
    e2.run();
    e2.start();
    //以后想要中等车的话可以增加相应中等配件的接口
}

以上就是一个针对产品族的工厂,用来生产一个产品,而不是一个配件。假如以后想生产一个中端汽车产品。就可以增加相应的类,实现汽车总工厂CarFactory

来生产。

 

三、工厂模式要点

简单工厂模式(静态工厂模式)

   虽然某种程度不符合面向对象规则(不符合开闭原则,每次新增内容都需要在原有代码上修改),但是实际使用最多。

工厂方法模式

   不修改已有类的前提下,通过增加新类来实现扩展。

抽象工厂模式

    不可以增加产品中某一个配件,可以增加一个具体的产品族。

 

四、应用场景

JDK中的Calendar的getInstance方法

JDBC中Connection对象的获取getConnection

Hibernate中SessionFactory创建Session

spring中的IOC容器创建管理bean对象的时候也是工厂模式

XML解析时的DocumentBuilderFactory创建解析器对象

反射中Class对象的newInstance方法。

 

 

 Java23种设计模式学习笔记【目录总贴】

参考资料:

  大话设计模式(带目录完整版).pdf

  HEAD_FIRST设计模式(中文版).pdf

  尚学堂_高淇_java300集最全视频教程_【GOF23设计模式】

posted @ 2017-02-15 23:52  chenxiangxiang  阅读(3662)  评论(0编辑  收藏  举报