博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
工厂方法模式
阅读量:5226 次
发布时间:2019-06-14

本文共 6663 字,大约阅读时间需要 22 分钟。

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     @Override21     public double getResult() {22         double result = 0;23         result = getNumberA () + getNumberB ();24         return result;25     }26 }27 28 class OperationSub extends Operation{29     @Override30     public double getResult() {31         double result = 0;32         result = getNumberA () - getNumberB ();33         return result;34     }35 }36 37 class OperationMul extends Operation{38     @Override39     public double getResult() {40         double result = 0;41         result = getNumberA () * getNumberB ();42         return result;43     }44 }45 46 class OperationDiv extends Operation{47     @Override48     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     @Override4     public void Send() {5         System.out.println("this is msgsender");6     }7 }
1 public class MailSender implements Sender {2 3     @Override4     public void Send() {5         System.out.println("this is mailsender!");6     }7 }

两个工厂类

1 public class SendmsgFactory implements Provider {2 3     @Override4     public Sender produce() {5         return new MsgSender();6     }7 }
1 public class SendmailFactory implements Provider {2 3     @Override4     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了,无需去改动现成的代码。这样做,拓展性较好,即依赖抽象不依赖具体原则的体现。

转载于:https://www.cnblogs.com/gdwkong/p/8413342.html

你可能感兴趣的文章
Android菜单详解(一)——理解android中的Menu
查看>>
正向代理与反向代理
查看>>
[JSOI2008]完美的对称
查看>>
【Android】Android 监听apk安装替换卸载广播
查看>>
各种推导式详解
查看>>
程序员能力矩阵
查看>>
Xamarin Error:Could not find android.jar for API Level 23.
查看>>
异常001
查看>>
Error: unknown argument: '-websockets'
查看>>
android 中管理短信
查看>>
MongoDB数据导出
查看>>
Ubuntu常用操作命令
查看>>
mybatis中resultType和resultMap的联系
查看>>
jquery 调用js成员
查看>>
iOS 上传的图片在HTML上显示时,图片方向信息(EXIF Orientation)异常
查看>>
Git
查看>>
JAVA通信系列三:Netty入门总结
查看>>
Java8之新特性--modules
查看>>
RPD Volume 172 Issue 1-3 December 2016 评论02
查看>>
jQuery --计算复选框被选中个数
查看>>