zoukankan      html  css  js  c++  java
  • 工厂方法模式

    1 工厂模式介绍

      1.1 定义:定义一个用于创建对象的接口,让子类绝对实例化哪一个类,工厂方法使一个类的实例化延迟到其子类。

      工厂方法模式通用类图:

      在工厂模式中,抽象产品类Product负责定义产品的共性,实现对事物最抽象的定义,Creator为抽象类创建类,也就是抽象工厂,具体如何创建产品类是有具体的实现工厂ConcreteCreator完成的。

      1.2 工厂方法模式的优点

    • 良好的封装性,代码结构清晰。
    • 扩展性非常优秀,在增加产品类的情况系下,只有适当的修改具体的工厂类或扩展一个工厂类,就可以“拥抱变化”。
    • 屏蔽产品类。产品类的实现如何变化,调用者无需关心,它只需关心产品的接口,只要接口保持不变,系统中的上层模块就不需要发生变化。
    • 解耦框架。高层模块只需要知道产品的抽象类,其他实现类都不用关心。

      1.3 工厂方法模式的使用场景

    2 工厂模式实现

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

      以实现一个计算器为例:

      整个过程涉及到三个对象,人(Program4类表示)、计算器(以OperationFactory类表示)、计算方式(计算方式中有多种,加减乘除等,但都属于计算方法,以一个父类Operation,加减乘除继承覆写方法即可)。整个示例类如下图:

     1 public class Program4 {
     2     public static void main(String[] args) {
     3         try {
     4             Scanner scanner = new Scanner (System.in);
     5 
     6             System.out.println ("请输入数字A:");
     7             double numberA = Double.parseDouble (scanner.nextLine ());
     8             System.out.println ("选择运算符(+、-、*、/):");
     9             String strOperate = scanner.nextLine ();
    10             System.out.println ("请输入数字B:");
    11             double numberB = Double.parseDouble (scanner.nextLine ());
    12             String strResult = "";
    13 
    14             if ( strOperate != "/" || numberB != 0){
    15                 Operation oper;
    16                 oper = OperationFactory.createOperate (strOperate);
    17                 oper.setNumberA (numberA);
    18                 oper.setNumberB (numberB);
    19                 
    20                 strResult = String.valueOf (oper.getResult ());
    21                 System.out.println ("结果为:"+strResult);
    22 
    23             }else {
    24                 System.out.println ("除数不能为零");
    25             }
    26 
    27             scanner.close ();
    28         } catch (Exception e) {
    29             throw new RuntimeException("您输入有误:"+e.getMessage ());
    30         }
    31     }
    32 }

     计算器(工厂)根据用户需求,选择(生成)符合需要的计算方式创建对应的实例对象,创建过程中需要需用户参与。

     1 public class OperationFactory {
     2     public static Operation createOperate(String operate) {
     3         Operation oper = null;
     4         switch (operate){
     5             case "+":
     6                 oper = new OperationAdd ();
     7                 break;
     8             case "-":
     9                 oper = new OperationSub ();
    10                 break;
    11             case "*":
    12                 oper = new OperationMul ();
    13                 break;
    14             case "/":
    15                 oper = new OperationDiv ();
    16                 break;
    17         }
    18         return oper;
    19     }
    20 }
     1 public class Operation{
     2     private double numberA = 0;
     3     private double numberB = 0;
     4 
     5     public double getNumberA() { return numberA; }
     6 
     7     public void setNumberA(double numberA) { this.numberA = numberA; }
     8 
     9     public double getNumberB() { return numberB; }
    10 
    11     public void setNumberB(double numberB) { this.numberB = numberB; }
    12 
    13     public double getResult(){ 
    14         double result = 0;
    15         return result;
    16     }
    17 }
    18 
    19 class OperationAdd extends Operation{
    20     @Override
    21     public double getResult() {
    22         double result = 0;
    23         result = getNumberA () + getNumberB ();
    24         return result;
    25     }
    26 }
    27 
    28 class OperationSub extends Operation{
    29     @Override
    30     public double getResult() {
    31         double result = 0;
    32         result = getNumberA () - getNumberB ();
    33         return result;
    34     }
    35 }
    36 
    37 class OperationMul extends Operation{
    38     @Override
    39     public double getResult() {
    40         double result = 0;
    41         result = getNumberA () * getNumberB ();
    42         return result;
    43     }
    44 }
    45 
    46 class OperationDiv extends Operation{
    47     @Override
    48     public double getResult() {
    49         double result = 0;
    50         result = getNumberA () / getNumberB ();
    51         return result;
    52     }
    53 }

     简单工厂的缺点,不符合“开放封闭原则,要增加新的功能(计算方式)时,需要去修改工厂类(增加分支)。

    2.2 多方法模式

    是对普通工厂方法模式的改进,在普通工厂方法模式中,如果传递的字符串出错,则不能正确创建对象,而多个工厂方法模式是提供多个工厂方法,分别创建对象。

     1 public class OperationFactory03 {
     2 
     3     public Operation add(){
     4         return new OperationAdd();
     5     }
     6 
     7     public Operation sub(){
     8         return new OperationSub ();
     9     }
    10 
    11     public Operation mul(){
    12         return new OperationMul();
    13     }
    14 
    15     public Operation div(){
    16         return new OperationDiv();
    17     }
    18 }
     1 public class FactoryTest {
     2 
     3     public static void main(String[] args) {
     4 
     5         OperationFactory03 factory03 = new OperationFactory03();
     6         Operation add = factory03.add();
     7         
     8         add.setNumberA(20);
     9         add.setNumberB(10);
    10         double result = add.getResult();
    11         System.out.println(result);
    12     }
    13 }

    2.3 静态工厂方法模式

    多个工厂方法模式里的方法置为静态的,不需要创建实例,直接调用即可。

     1 public class OperationFactory {
     2 
     3     public static Operation add(){
     4         return new OperationAdd();
     5     }
     6 
     7     public static Operation sub(){
     8         return new OperationSub ();
     9     }
    10 
    11     public static Operation mul(){
    12         return new OperationMul();
    13     }
    14 
    15     public static Operation div(){
    16         return new OperationDiv();
    17     }
    18 }
     1 //调用类
     2 public class FactoryTest {
     3 
     4     public static void main(String[] args) {
     5 
     6         Operation add = OperationFactory02.add();
     7         add.setNumberA(20);
     8         add.setNumberB(10);
     9         double result = add.getResult();
    10         System.out.println(result);
    11         
    12     }
    13 }

      总体来说,工厂模式适合:凡是出现了大量的产品需要创建,并且具有共同的接口时,可以通过工厂方法模式进行创建。在以上的三种模式中,第一种如果传 入的字符串有误,不能正确创建对象,第三种相对于第二种,不需要实例化工厂类,所以,大多数情况下,我们会选用第三种——静态工厂方法模式。

    3  抽象工厂模式

      工厂方法模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改,这违背了闭包原则,所以,从设计角度考虑, 有一定的问题,如何解决?就用到抽象工厂模式,创建多个工厂类,这样一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的代码。因为抽象 工厂不太好理解,我们先看看图,然后就和代码,就比较容易理解。

    接口类

    1 public interface Sender {
    2     public void Send();
    3 }

    两个实现类

    1 public class MsgSender implements Sender{
    2 
    3     @Override
    4     public void Send() {
    5         System.out.println("this is msgsender");
    6     }
    7 }
    1 public class MailSender implements Sender {
    2 
    3     @Override
    4     public void Send() {
    5         System.out.println("this is mailsender!");
    6     }
    7 }

    两个工厂类

    1 public class SendmsgFactory implements Provider {
    2 
    3     @Override
    4     public Sender produce() {
    5         return new MsgSender();
    6     }
    7 }
    1 public class SendmailFactory implements Provider {
    2 
    3     @Override
    4     public Sender produce() {
    5         return new MailSender();
    6     }
    7 }

    提供一个接口

    1 public interface Provider {
    2     public Sender produce();
    3 }

    测试类

    1 public class FactoryTest {
    2     public static void main(String[] args) {
    3         Provider provider = new SendmailFactory();
    4         Sender sender = provider.produce();
    5         sender.Send();
    6     }
    7 }

      其实这个模式的好处就是,如果你现在想增加一个功能:发及时信息,则只需做一个实现类,实现Sender接口,同时做一个工厂类,实现Provider接口,就OK了,无需去改动现成的代码。这样做,拓展性较好,即依赖抽象不依赖具体原则的体现。

  • 相关阅读:
    谷歌将用QUIC传输层技术加速互联网
    无人自助洗车机漏洞
    什么是区块链,为什么它越来越受欢迎
    域名Whois数据和隐私是最大风险
    什么原因?全球许多网络提供商推迟部署IPv6
    FFT/NTT复习笔记&多项式&生成函数学习笔记Ⅱ
    C#中读写INI配置文件
    C#读取和导出EXCEL类库(可操作多个SHEET)
    Javascript刷新页面的几种方法
    用C#抓取AJAX页面的内容
  • 原文地址:https://www.cnblogs.com/gdwkong/p/8413342.html
Copyright © 2011-2022 走看看