软件设计模式学习(五)工厂方法模式

工厂方法模式

工厂方法模式是简单工厂模式的延伸,它继承了简单工厂模式的优点,同时弥补了简单工厂的缺陷,更好地符合开闭原则的要求,增加新的具体产品对象不需要对已有系统作任何修改。


模式定义

工厂方法模式又称为工厂模式,也叫虚拟构造器模式或者多态工厂模式,属于类创建模式。在工厂模式中,工厂父类负责定义产品对象的公共接口,而子工厂模式负责生成具体的产品对象,这样做的目的是将产品类实例化操作延迟到工厂子类中完成,即通过工厂子类来确定实例化哪一个对象。


模式结构

软件设计模式学习(五)工厂方法模式_第1张图片

  1. Product(抽象产品)

    抽象产品是定义产品的接口,是工厂方法模式所创建对象的超类型,也就是产品对象的共同父类接口

  2. ConcreteProduct(具体产品)

    具体产品实现抽象产品接口,某种类型的具体产品由专门具体创建

  3. Facory(抽象工厂)

    在抽象工厂类中,声明工厂方法,用于返回一个产品。抽象工厂是工厂方法模式的核心,任何在模式中创建对象的工厂类都必须实现该接口。

  4. ConcreteFactory(具体工厂)

    具体工厂是抽象工厂类的子类,实现了抽象工厂定义的工厂方法,返回一个具体产品类的实例。


模式分析

在工厂方法模式中,核心的工厂类不再负责所有产品的创建,而是将具体创建的工作交给了子类。核心类仅仅给出具体工厂实现的接口,而不负责哪一个产品被实例化的细节,使得工厂方法模式允许系统在不修改工厂角色的情况下引进新产品。

实际的开发应用中,不直接使用new关键字来创建对象,而是将具体类的类名写入配置文件,在通过java反射机制,读取XML格式的配置文件,根据存储在XML文件的类名字符串生成对象。


工厂方法模式实例之手机工厂

  1. 实例说明

    之前的简单工厂模式时我们也创建过一个类似实例,但却是违反了开闭原则的。通过工厂方法模式进行一次重构,将原有工厂进行分割,为每种品牌的手机提供一个子工厂,使整个系统具有更好的灵活性和可扩展性。

  2. 实例类图

软件设计模式学习(五)工厂方法模式_第2张图片

  1. 实例代码及解释

    1. 抽象产品类Phone

      public abstract class Phone {
      
          public abstract void use();
      }
      
    2. 具体产品类HuaweiPhone

      public class HuaweiPhone extends Phone {
      
          @Override
          public void use() {
      
              System.out.println("华为手机使用中....");
          }
      }
      
    3. 具体产品类XiaomiPhone

      public class XiaomiPhone extends Phone {
      
          @Override
          public void use() {
      
              System.out.println("小米手机使用中....");
          }
      }
      
    4. 抽象工厂类PhoneFactory

      public interface PhoneFactory {
      
          Phone producePhone();
      }
      
    5. 具体工厂类HuaweiPFactory

      public class HuaweiPFactory implements PhoneFactory {
          @Override
          public Phone producePhone() {
              System.out.println("华为工厂生产华为手机......");
              return new HuaweiPhone();
          }
      }
      
    6. 具体工厂类XiaomiPFactory

      public class XiaomiPFactory implements PhoneFactory {
      
          @Override
          public Phone producePhone() {
      
              System.out.println("小米工厂生产小米手机......");
              return new XiaomiPhone();
          }
      
      }
      
    7. XML操作工具类

      public class XMLUtilPhone {
      
          public static Object getBean() throws Exception {
      
              //创建解析器工厂
              DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
              //创建解析器
              DocumentBuilder builder = builderFactory.newDocumentBuilder();
              //得到document
              Document document = builder.parse("configPhone.xml");
              //获取包含品牌名称的文本节点
              NodeList brandNameList = document.getElementsByTagName("factoryName");
              Node classNode = brandNameList.item(0).getFirstChild();
              String factoryName = classNode.getNodeValue().trim();
      
      //        System.out.println(factoryName);
      
              Class c = Class.forName("com.factoryMethod." + factoryName);
              Object o = c.newInstance();
              return o;
          }
      }
      
    8. 配置文件

      
      
         XiaomiPFactory
      
      
    9. 测试类

      public class Test {
      
          public static void main(String[] args) throws Exception {
      
              PhoneFactory phoneFactory = (PhoneFactory) XMLUtilPhone.getBean();
      
              Phone phone = phoneFactory.producePhone();
      
              phone.use();
          }
      }
      
    10. 结果分析

      如果在配置文件将节点中内容设置为 XiaomiPFactory,则输出结果如下:
      在这里插入图片描述
      如果在配置文件将节点中内容设置为 XiaomiPFactory,则输出结果如下:
      在这里插入图片描述
      如果需要增加新的类型的手机,则首先要增加一个新的具体产品类,再增加对于的具体工厂类。

你可能感兴趣的:(软件设计模式学习(五)工厂方法模式)