zoukankan      html  css  js  c++  java
  • 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)………………

  • 相关阅读:
    Centos7 keepalived 修改日志路径
    mysql 双主复制 centos7
    CentOs 7 安装mysql5.7.18(二进制版本)
    oracle、mysql新增字段,字段存在则不处理
    mysql+ibatis 批量插入
    oracle+ibatis 批量插入-支持序列自增
    oracle 批量插入-支持序列自增
    sftp上传
    java
    mysql
  • 原文地址:https://www.cnblogs.com/cao-lei/p/8143731.html
Copyright © 2011-2022 走看看