工厂方法模式

匿名 (未验证) 提交于 2019-12-02 21:53:32

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 }

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

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

接口类

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了,无需去改动现成的代码。这样做,拓展性较好,即依赖抽象不依赖具体原则的体现。

文章来源: 工厂方法模式
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!