zoukankan      html  css  js  c++  java
  • 一天一个设计模式——工厂方法(FactoryMethod)模式

    一、模式说明

      在前一个模板方法(Template Method)模式中,父类定义了处理流程,而流程中用到的方法交给子类去实现。类似的,在工厂方法模式中,父类决定如何生成实例,但并不决定所要生成的具体类,具体的处理交由子类来处理。这样可以将生成实例的框架和实例本身解耦。

      工厂方法模式在很多框架中都有用到,在面试中也问的比较多的,需要重点理解把握。

    二、工厂方法(Factory Method)模式类图

    三、工厂方法(Factory Method)模式中的角色

    • Product产品类【框架】:定义了工厂方法模式生成的实例应该持有哪些接口。
    • Creater创建者类【框架】:负责生成Product角色的抽象类。Creater角色对最终生成的实例是一无所知的,它只知道,只要调用Product角色和工厂方法(factoryMethod),就可以生成Product的实例,无需调用new方法,这样可以将父类和其他具体类耦合。
    • ConreteProduct具体的产品类:工厂方法生成的具体产品。
    • ConcreteCreater具体的创建者类:负责生成具体的产品。

    四、工厂方法(Factory Method)代码示例:

    1、模式框架类的创建,Product类:

    package com.designpattern.cn.factorymethodpattern.patternframework;
    
    public abstract class Product {
        public abstract void use();
    }
    View Code

    2、模式框架类的创建,Factory类:

    package com.designpattern.cn.factorymethodpattern.patternframework;
    
    public abstract class Factory {
        public final Product create(String owner){
            Product product = this.createProduct(owner);
            this.registerProduct(product);
            return product;
        }
    
        protected abstract Product createProduct (String owner);
        protected abstract void registerProduct(Product product);
    }
    View Code

    3、模式实现类,IDCard身份证类:

    package com.designpattern.cn.factorymethodpattern.patterndemostrate;
    
    import com.designpattern.cn.factorymethodpattern.patternframework.Product;
    
    public class IDCard extends Product {
        private String owner;
        IDCard(String owner){
            System.out.println("制作" + owner + "的ID卡");
            this.owner = owner;
        }
    
        public void use(){
            System.out.println("使用" + this.owner + "的ID卡");
        }
    
        public String getOwner() {
            return owner;
        }
    }
    View Code

    4、模式实现类,IDCardFactory类:

    package com.designpattern.cn.factorymethodpattern.patterndemostrate;
    
    import com.designpattern.cn.factorymethodpattern.patternframework.Factory;
    import com.designpattern.cn.factorymethodpattern.patternframework.Product;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class IDCardFactory extends Factory {
        private List owners = new ArrayList();
        protected Product createProduct(String owner){
            return new IDCard(owner);
        }
    
        protected void registerProduct(Product product){
            owners.add(((IDCard)product).getOwner());
        }
    
        public List getOwners(){
            return owners;
        }
    }
    View Code

    5、Main方法类与运行结果:

    上面的代码示例中,工厂模式的createProduct是一个抽象方法,必须在子类中实现该方法,具体可以选择三种实现方式:

    1. 指定其为抽象方法,如同上面的代码示例一样;
    2. 为其实现默认处理:

    public Product createProduct(String name){
    return new Product(name);
    }

    如果采用这种方式,Product类就不能定义为抽象类。

           3.抛出异常的方式:

    public Product createProduct(String name){
    throw new FactoryMethodRuntimeException();
    }

    这样一来,就必须在子类中重写该方法,否则会抛出异常。

    五、工厂方法(Factory Method)模式相关的模式

    • 模板方法(Template Method)模式:工厂方法模式是模板方法模式的典型应用,工厂方法中的createProduct就是模板方法。
    • 单例模式(Singleton):工厂方法模式中,具体的创建者角色(上例中的IDCardFactory)类,可以设计为单例模式,因为程序中没有必要存在多个创建者角色的实例(后续学习到单例模式时再回头修改这个示例)。
    • 组合(Composite)模式:将对象组合成树形结构以表示“部分-整体”的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。工厂方法模式中的Creater和ConcreteCreater对象可以用到该模式。
    • 迭代器(Iterator)模式:在迭代器模式中,使用iterator方法生成Iterator实例时,会使用工厂方法模式。
  • 相关阅读:
    [每日一题系列] LeetCode 1071. 字符串的最大公因子
    [每日一题系列] LeetCode 1013. 将数组分成和相等的三个部分
    git diff (19)
    WinDbg探究CLR底层(1)
    使用LINQ、Lambda 表达式 、委托快速比较两个集合,找出需要新增、修改、删除的对象
    转MySQL遇到的语法差异及解决方案
    批量拼脚本神器-NimbleText
    Visual Studio 2017中使用正则修改部分内容
    如何使用ILAsm与ILDasm修改.Net exe(dll)文件
    在Windows上安装Elasticsearch v5.4.2
  • 原文地址:https://www.cnblogs.com/zheng-hong-bo/p/11079929.html
Copyright © 2011-2022 走看看