第四式 工厂模式

工厂模式

一 简单工厂

  我们去4s店里面买车下订单,然后汽车工厂根据我们的订单来生成对应的车辆。

 1 public class CarShop {
 2     public Car order(String type){
 3         Car car = null;
 4         if("Benz".equals(type)){
 5             car = new BenzCar();
 6         }else if("Tyota".equals(type)){
 7             car = new ToytaCar();
 8         }else{
 9             return car;
10         }
11         car.design();
12         car.assemble();
13         car.test();
14         return car;
15     }
16 }

这样的代码实现,会随着车辆种类的变多变成if else 地狱,后期对车型的维护会变得无比艰难,所有需要创建Car类的地方都要维护到。我们试着将代码中会变化的部分抽离出来并封装:
 1 public class SimpleCarFactory {
 2     public Car createCar(String type){
 3         Car car = null;
 4         if("Benz".equals(type)){
 5             car = new BenzCar();
 6         }else if("Tyota".equals(type)){
 7             car = new ToytaCar();
 8         }else{
 9             return car;
10         }
11         return car;
12     }
13 }
14 public class CarShop {
15     SimpleCarFactory simpleCarFactory;
16 
17     public CarShop(SimpleCarFactory simpleCarFactory){
18         this.simpleCarFactory = simpleCarFactory;
19     }
20 
21     public Car order(String type){
22         Car car = simpleCarFactory.createCar(type);
23         car.design();
24         car.assemble();
25         car.test();
26         return car;
27     }
28 }

这样分离之后,虽然if else地狱依然存在,但是在别的需要创建Car对象的地方就不用重复维护了。
简单工厂模式与其说是一种设计模式,不如说是一种编程习惯。类图如下:

  

二 工厂模式

  当我们的汽车销售形成规模,在各地都需要4s店,而各地对汽车的审美都有自己的要求,即需要一些地方化的服务。我们之前一刀切式地在order方法中根据车型来创建

  汽车对象的方式需要进行调整了,因为它不能满足需求了。代码调整如下:

  1.将CarShop类中createCar方法抽象出来,让各地的分店自行实现自己的。

 1 public abstract class CarShop {
 2     public Car order(String type){
 3         Car car = createCar(type);
 4         car.design();
 5         car.assemble();
 6         car.test();
 7         return car;
 8     }
 9 
10     public abstract Car createCar(String type);
11 }

 

  2.北京和大连的4s店

 1 public class BeijingCarShop extends CarShop {
 2     public Car createCar(String type) {
 3         Car car = null;
 4         if("Benz".equals(type)){
 5             car = new BeijingBenzCar();
 6         }else if("Tyota".equals(type)){
 7             car = new BeijingTyotaCar();
 8         }else{
 9             return car;
10         }
11         return car;
12 
13     }
14 }
15 public class DalianCarShop extends CarShop {
16     public Car createCar(String type) {
17         Car car = null;
18         if("Benz".equals(type)){
19             car = new DalianBenzCar();
20         }else if("Tyota".equals(type)){
21             car = new DalianTyotaCar();
22         }else{
23             return car;
24         }
25         return car;
26 
27     }
28 }

 

  工厂方法用来处理对象的创建,并将这样的行为封装在子类中。这样程序中超类的代码和子类对象的创建代码就解耦了。

  

  

   工厂方法模式:定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。

  设计原则:依赖倒置原则--要依赖抽象,不要依赖具体类。

三 抽象工厂模式

   当我们的需求变更为为不同的品牌的车生产不同配置的车时,也就是说同样车型的车,有了不同的配置。配置大概抽出几个,如轮胎,引擎,座椅等。

  面向接口设计原则,我们将这些个配置也全都抽象出来,这样上面的工厂模式就不适合了。我们来看看抽象工厂模式。

  抽象工厂模式:提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。

  类图如下:

  

  代码实现:

  1.配件接口,及高低端配件的实现类

 

 1 //引擎
 2 
 3 public interface Engine {
 4     public void run();
 5     public void start();
 6 }
 7 
 8 class LuxuryEngine implements Engine{
 9 
10     public void run() {
11         System.out.println("跑得快");
12     }
13 
14     public void start() {
15         System.out.println("启动快");
16     }
17 }
18 
19 class LowEngine implements Engine{
20 
21     public void run() {
22         System.out.println("跑得慢");
23     }
24 
25     public void start() {
26         System.out.println("启动慢");
27     }
28 }
29 //轮胎
30 public interface Tyre {
31     public void revolve();
32 }
33 
34 class LuxuryTyre implements Tyre{
35 
36     public void revolve() {
37         System.out.println("耐磨");
38     }
39 }
40 
41 class LowTyre implements Tyre{
42 
43     public void revolve() {
44         System.out.println("不耐磨");
45     }
46 }
47 //座椅
48 public interface Seat {
49     public void message();
50 }
51 
52 class LuxurySeat implements Seat{
53 
54     public void message() {
55         System.out.println("真皮沙发");
56     }
57 }
58 
59 class LowSeat implements Seat{
60 
61     public void message() {
62         System.out.println("塑料沙发");
63     }
64 }

 

  2.抽象工厂类
1 public interface CarFactory {
2     Engine createEngine();
3     Tyre createTyre();
4     Seat createSeat();
5 }

  3.高低端工厂实现类
 1 public class LowCarFactory implements CarFactory {
 2     public Engine createEngine() {
 3         return new LowEngine();
 4     }
 5 
 6     public Tyre createTyre() {
 7         return new LowTyre();
 8     }
 9 
10     public Seat createSeat() {
11         return new LowSeat();
12     }
13 }
14 public class LuxuryCarFactory implements CarFactory {
15     public Engine createEngine() {
16         return new LuxuryEngine();
17     }
18 
19     public Tyre createTyre() {
20         return new LuxuryTyre();
21     }
22 
23     public Seat createSeat() {
24         return new LuxurySeat();
25     }
26 }

 

  4.测试
1 public class Client {
2     public static void main(String[] args){
3         CarFactory factory = new LowCarFactory();
4         Engine e = factory.createEngine();
5         e.start();
6         e.run();
7     }
8 }

  运行结果:

  

 四 总结

  要点:

  简单工厂模式:虽然某种程度不符合设计原则,但实际使用最多

  工厂方法模式:不修改已有类的前提下,通过增加新的工厂类实现扩展

  抽象工厂模式:不可以增加产品,但可以增加产品族

  应用场景:

  JDK中Calendar的getInstance方法

  JDBC中Connection对象的获取

  Spring中IOC容器创建管理bean对象

  反射中Class对象的newInstance()

  


posted @ 2019-04-07 21:20  spiritofstorm  阅读(172)  评论(0编辑  收藏  举报