zoukankan      html  css  js  c++  java
  • 初学设计模式【5】工厂方法模式——FactoryMethod

      在初学设计模式【4】简单工厂模式——SimpleFactory中介绍了工厂模式中最简单的一个模式——简单工厂模式。正如它的名字一样,此模式的确很简单,但缺点也很明显。如果需要添加新的产品类时,就需要修改工厂类。很明显这违反了一个重要的OO设计原则——开闭原则。为了克服简单工厂模式的这个问题,就有了一个新的工厂模式——工厂方法模式。

    定义

      定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。

    UML类图

    分析:1>Product与Creator都是抽象类,Creator中有一个抽象工厂方法factoryMethod,此方法也是此模式的核心。各具体创建者类必须实现此方法,以实现不同的子类。

         2>核心工厂类如上图的Creator不再负责具体产品实例的创建,而仅仅是负责给出具体工厂子类必须实现的接口,让工厂子类去负责具体产品实例的创建。

         3>因为此模式将实例化推迟到了子类中,所以如果我们想增加新产品,只需要重新写一个继承自抽象创建者类的具体创建者类,实现factoryMethod方法即可。除此之外不需要修改任何代码。严格遵守了“开闭原则”。

    实例

    例子uml图:

    应该是很清楚的,就不多解释了。

    代码

      1>Phone

    View Code
     1 public abstract class Phone {
     2     String name;
     3     String IMEI;
     4     String color;
     5     String weight;
     6 
     7     public Phone(String name) {
     8         this.name = name;
     9     }
    10 
    11     public void dial() {
    12         System.out.println(name + " is dialling");
    13     }
    14 
    15     public void sendMessage() {
    16         System.out.println(name + " is sending Message");
    17     }
    18 
    19     public void phoneInfo() {
    20         System.out.println("this phone info:" + toString());
    21     }
    22 
    23     @Override
    24     public String toString() {
    25         return "Phone [name=" + name + ", IMEI=" + IMEI + ", color=" + color
    26                 + ", weight=" + weight + "]";
    27     }
    28 
    29 }

      2>MotoPhone,NokiaPhone

    View Code
     1 public class MotoPhone extends Phone {
     2 
     3     public MotoPhone(String name) {
     4         super(name);
     5     }
     6 
     7 }
     8 
     9 
    10 public class NokiaPhone extends Phone {
    11 
    12     public NokiaPhone(String name) {
    13         super(name);
    14     }
    15 
    16 }

      3>PhoneFactory

    View Code
     1 public abstract class PhoneFactory {
     2     /**
     3      * 工厂方法
     4      * 
     5      * @return 具体种类的phone
     6      */
     7     public abstract Phone factoryMethod();
     8 
     9     // 下面可以定义一些其它的方法,完成与产品相关的其它业务逻辑
    10     public Phone createPhone() {
    11         Phone phone = factoryMethod();
    12         System.out.println(phone.name + " is preparing");
    13         phone.IMEI = "fjieww892fjk3j292jfjjj933";
    14         phone.color = "Red";
    15         phone.weight = "120g";
    16         System.out.println(phone.name + " prepare finished");
    17         return phone;
    18     }
    19 }

      4>MotoPhoneFactory,NokiaPhoneFactory 

    public class NokiaPhoneFactory extends PhoneFactory {
    
    	@Override
    	public Phone factoryMethod() {
    		return new NokiaPhone("Nokia");
    	}
    
    }
    
    
    public class MotoPhoneFactory extends PhoneFactory {
    
    	@Override
    	public Phone factoryMethod() {
    		return new MotoPhone("MotoRola");
    	}
    
    }

      5>测试

    View Code
     1 import org.junit.Test;
     2 
     3 public class Testt {
     4 
     5     @Test
     6     public void test() {
     7         Phone phone = new MotoPhoneFactory().createPhone();
     8         phone.phoneInfo();
     9         phone.sendMessage();
    10     }
    11 }

       输出:

     

    分析:

      可以看到,如果我们想增加新的手机种类,比如Iphone,只需继承PhoneFactory写一个IphoneFactory重写里面的工厂方法,当然还要写一个Iphone的具体产品类。

  • 相关阅读:
    1013:温度表达转化
    1012:计算多项式的值
    1012:计算多项式的值
    1012:计算多项式的值
    数据结构——线性表
    数据结构——线性表
    数据结构——线性表
    SqlSever查询某个表的列名称、说明、备注、注释,类型等
    SqlSever查询某个表的列名称、说明、备注、注释,类型等
    SQL:将查询结果插入到另一个表的三种情况
  • 原文地址:https://www.cnblogs.com/byghui/p/3069810.html
Copyright © 2011-2022 走看看