GOF23设计模式之工厂模式(factory)

一、工厂模式概述

  实现了创建者和调用者的分离

  (1)分类

    ①简单工厂模式

      虽然某种程度不符合设计原则,但实际使用最多。

    ②工厂方法模式

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

    ③抽象工厂模式

      不可以增加产品,可以增加产品族。

二、不使用工厂模式时

  1.创建一个汽车的接口

1 public interface Car {
2     void run();
3 }

  2.创建两个实现汽车接口的类:

1 public class Audi implements Car {
2 
3     public void run() {
4         System.out.println("奥迪在跑...");
5     }
6     
7 }
1 public class Byd implements Car {
2 
3     public void run() {
4         System.out.println("比亚迪在跑...");
5     }
6     
7 }

  3.客户端创建实例:

 1 public class Client {
 2     
 3     public static void main(String[] args) {
 4         Car c1 = new Audi();
 5         Car c2 = new Byd();
 6         
 7         c1.run();
 8         c2.run();
 9     }
10     
11 }

  控制台输出:

奥迪在跑...
比亚迪在跑...

  当客户没有需求改动时,完全可以不使用工厂模式。但是当需要创建更多实例或者需要频繁更改时,只需要引入工厂或者更改工厂类中的代码就可以了,这样就实现了解耦,是工厂模式的一大好处。

三、简单工厂(simplefactory)

  简单工厂模式也叫静态工厂模式,就是工厂类一般使用静态方法,通过接收的参数的不同来返回不同的对象实例。

  缺点:对于增加新产品无能为力!不修改代码的话,是无法扩展的。

  1.创建接口和实现类

1 public interface Car {
2     void run();
3 }
1 public class Audi implements Car {
2 
3     public void run() {
4         System.out.println("奥迪在跑...");
5     }
6     
7 }
1 public class Byd implements Car {
2 
3     public void run() {
4         System.out.println("比亚迪在跑...");
5     }
6     
7 }

  2.创建简单工厂类

 1 public class CarFactory {
 2     
 3     public static Car creatCar(String type) {
 4         if (type.equals("奥迪")) {
 5             return new Audi();
 6         } else if (type.equals("比亚迪")){
 7             return new Byd();
 8         }
 9         return null;
10     }
11 
12 }

  3.测试

 1 public class Client {
 2 
 3     public static void main(String[] args) {
 4         Car c1 = CarFactory.creatCar("奥迪");
 5         Car c2 = CarFactory.creatCar("比亚迪");
 6         
 7         c1.run();
 8         c2.run();
 9 
10     }
11 }

  控制台输出:

奥迪在跑...
比亚迪在跑...

  4.或者创建另一种简单(静态)工厂类

 1 public class CarFactory {
 2     
 3     public static Car creatAudi() {
 4         return new Audi();
 5     }
 6     
 7     public static Car creatByd() {
 8         return new Byd();
 9     }
10 }

  5.测试

 1 public class Client {
 2 
 3     public static void main(String[] args) {
 4         Car c1 = CarFactory.creatAudi();
 5         Car c2 = CarFactory.creatByd();
 6         
 7         c1.run();
 8         c2.run();
 9     }
10 }

  控制台输出:

奥迪在跑...
比亚迪在跑...

  通过工厂类创建实例,实现解耦。

四、工厂方法(factorymethod)

  一个类对应一个工厂实现类,避免了开闭原则的弊端,更容易扩展代码。但是从复杂度来分析,简单工厂模式更优,因为对客户而言,简单工厂更简单。

  1.创建汽车接口和汽车工厂接口

1 public interface Car {
2     void run();
3 }
1 public interface CarFactory {
2     Car createCar();
3 }

  2.创建汽车的接口和汽车工厂方法的实现类

1 public class Audi implements Car {
2 
3     public void run() {
4         System.out.println("奥迪在跑...");
5     }
6     
7 }
1 public class AudiFactory implements CarFactory {
2 
3     public Car createCar() {
4         return new Audi();
5     }
6 
7 }
1 public class Byd implements Car {
2 
3     public void run() {
4         System.out.println("比亚迪在跑...");
5     }
6     
7 }
1 public class BydFactory implements CarFactory {
2 
3     public Car createCar() {
4         return new Byd();
5     }
6 
7 }

  3.测试

 1 public class Client {
 2     
 3     public static void main(String[] args) {
 4         Car c1 = new AudiFactory().createCar();
 5         Car c2 = new BydFactory().createCar();
 6         
 7         c1.run();
 8         c2.run();
 9     }
10 
11 }

  控制台输出:

奥迪在跑...
比亚迪在跑...

  不再与实际类打交道,而通过工厂来创建对象,实现解耦。增加新的产品也更加方便。

  4.增加新的产品

1 public class Benz implements Car {
2 
3     public void run() {
4         System.out.println("奔驰在跑...");
5     }
6 
7 }
1 public class BenzFactory implements CarFactory {
2 
3     public Car createCar() {
4         return new Benz();
5     }
6     
7 
8 }

  5.测试

 1 public class Client {
 2     
 3     public static void main(String[] args) {
 4         Car c1 = new AudiFactory().createCar();
 5         Car c2 = new BydFactory().createCar();
 6         Car c3 = new BenzFactory().createCar();
 7         
 8         c1.run();
 9         c2.run();
10         c3.run();
11     }
12 
13 }

  控制台输出:

奥迪在跑...
比亚迪在跑...
奔驰在跑...

五、抽象工厂

  抽象工厂模式用来生产不同产品族的全部产品。(对于新增加某一个完整的产品,无能为力;仅支持增加产品族;)

  产品族: 发动机 座椅 轮胎 是汽车的一个产品族

  抽象工厂模式是工厂模式的一种特殊版本,在有多个业务品种、业务分类时,通过抽象工厂模式产生需要的对象是一种非常好的解决方式。

  1.创建高低端产品族的接口和实现类

 1 /**
 2  * 创建汽车产品族中的发动机接口
 3  * @author CL
 4  *
 5  */
 6 public interface Engine {
 7     void run();
 8     void start();
 9 }
10 
11 /**
12  * 高端发动机实现类
13  */
14 class LuxuryEngine implements Engine {
15 
16     public void run() {
17         System.out.println("转速高!");
18     }
19 
20     public void start() {
21         System.out.println("可以自动启停!");        
22     }
23     
24 }
25 
26 /**
27  * 低端发动机实现类
28  */
29 class LowEngine implements Engine {
30     public void run() {
31         System.out.println("转速慢!");
32     }
33 
34     public void start() {
35         System.out.println("不可以自动启停!");        
36     }
37     
38 }
 1 /**
 2  * 创建汽车产品族中的座椅接口
 3  * @author CL
 4  *
 5  */
 6 public interface Seat {
 7     void massage();
 8 }
 9 
10 /**
11  * 高端座椅的实现类
12  */
13 class LuxurySeat implements Seat {
14 
15     public void massage() {
16         System.out.println("可以按摩!");
17     }
18     
19 }
20 
21 /**
22  * 低端座椅的实现类
23  */
24 class LowSeat implements Seat {
25 
26     public void massage() {
27         System.out.println("不可以按摩!");
28     }
29     
30 }
 1 /**
 2  * 创建汽车产品族的轮胎接口
 3  * @author CL
 4  *
 5  */
 6 public interface Tyre {
 7     void abrasion();
 8 }
 9 
10 /**
11  * 高端轮胎的实现类
12  */
13 class LuxuryTyre implements Tyre {
14 
15     public void abrasion() {
16         System.out.println("磨损慢!");
17     }
18     
19 }
20 
21 /**
22  * 低端轮胎的实现类
23  */
24 class LowTyre implements Tyre {
25 
26     public void abrasion() {
27         System.out.println("磨损快!");
28     }
29     
30 }

  2.创建高端汽车工厂和低端汽车工厂

 1 /**
 2  * 创建高端汽车的实现类工厂
 3  * @author CL
 4  *
 5  */
 6 public class LuxuryCarFactory implements CarFactory {
 7 
 8     /**
 9      * 制造高端发动机
10      */
11     public Engine creatEngine() {
12         return new LuxuryEngine();
13     }
14 
15     /**
16      * 制造高端座椅
17      */
18     public Seat creatSeat() {
19         return new LuxurySeat();
20     }
21 
22     /**
23      * 制造高端轮胎
24      */
25     public Tyre creatTyre() {
26         return new LuxuryTyre();
27     }
28     
29 }
 1 /**
 2  * 创建低端汽车的实现类工厂
 3  * @author CL
 4  *
 5  */
 6 public class LowCarFactory implements CarFactory {
 7 
 8     /**
 9      * 制造低端发动机
10      */
11     public Engine creatEngine() {
12         return new LowEngine();
13     }
14 
15     /**
16      * 制造低端座椅
17      */
18     public Seat creatSeat() {
19         return new LowSeat();
20     }
21 
22     /**
23      * 制造低端轮胎
24      */
25     public Tyre creatTyre() {
26         return new LowTyre();
27     }
28     
29 }

  3.测试

 1 /**
 2  * 使用抽象工厂模式创建高端汽车发动机
 3  *         创建低端汽车轮胎
 4  * @author CL
 5  *
 6  */
 7 public class Client {
 8     
 9     public static void main(String[] args) {
10         //需要低端发动机
11         CarFactory factory = new LowCarFactory();
12         Engine e = factory.creatEngine();
13         e.run();
14         e.start();
15         
16         System.out.println("----------------");
17         
18         //需要高端轮胎
19         CarFactory carFactory = new LuxuryCarFactory();
20         Tyre t = carFactory.creatTyre();
21         t.abrasion();
22     }
23 
24 }

  控制台输出:

转速慢!
不可以自动启停!
----------------
磨损慢!

六、如何选择工厂模式

  实际应用:简单工厂模式  

  增加产品:工厂方法模式

  增加产品族:抽象工厂模式

七、工厂模式常见应用场景

  (1)JDK中Calendar的getInstance方法;

  (2)JDBC中Connection对象的获取;

  (3)Hibernate中sessionFactory创建Session;

  (4)Spring中IOC容器创建管理bean对象;

  (5)XML解析时的DocumentBuilderFactory创建解析器对象;

  (6)反射中Class对象的newInstance();

  (7)………………

posted @ 2017-12-29 15:27  C3Stones  阅读(394)  评论(0编辑  收藏  举报