• 第四式 工厂模式


    工厂模式

    一 简单工厂

      我们去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()

      

    
    
  • 相关阅读:
    mysqlEasyHelper(待完善)
    入门day2
    入门day1
    c# 多态的理解
    c# 简单任务控制
    c# 陌生的关键字
    从0来搭建超灵活的MVP商用框架<三>-------网络层加入RxJava、事件总线封装、Dagger2集成
    从0来搭建超灵活的MVP商用框架<二>-------APP基础配置、Okhttp+Retrofit封装
    从0来搭建超灵活的MVP商用框架<一>-------从MVC至MVP的转变、通用网络切换框架
    IOC注入框架设计<三>-------Android Studio插件开发来自动生成ButterKnife相关代码
  • 原文地址:https://www.cnblogs.com/bwyhhx2018/p/10666220.html
Copyright © 2020-2023  润新知