zoukankan      html  css  js  c++  java
  • 【图解设计模式四】Factory Method 模式

    将实例的生成交给子类

    一、知识概述

    Factory Method 模式是指,在父类中定义生成实例的框架,在子类中实现具体处理。Factory Method 由Template Method 演变而来,其主要包含四种角色。

    • Product:为产品,属于框架内部,负责声明产品实例所需的方法
    • Creator:为创建者,属于框架内部,不仅负责实现模板方法,还负责声明在模板方法中所使用到的抽象方法
    • ConcreteProduct:为具体产品,负责具体实现Product角色中声明的抽象方法
    • ConcreteCreator:为具体的创建者,负责具体实现Creator角色中声明的抽象方法

    二、示例程序

    以下为实现Factory Method 模式的示例程序,这段示例程序的作用是,利用工厂流水线制作产品,且根据不同的具体加工可以生产不同的产品。

    类图示例

    Tips: 方法区上的类之间可以循环依赖,堆上的实例不可以循环依赖,包之间不可以循环依赖。
    

    程序清单

    需求框架

    /**
     * 声明需求方法的抽象类,并调用所声明的方法进行具体处理
     */
    public abstract class Factory {
        // 声明方法
        protected abstract Product createProduct(String owner);
        protected abstract void registerProduct(Product product);
    
        // 模板方法
        public final Product create(String owner) {
            Product p = createProduct(owner);
            registerProduct(p);
            return p;
        }
    }
    
    /**
     * 声明需求方法的抽象类
     */
    public abstract class Product {
        // 声明方法
        public abstract void use();
    }
    

    行为测试

    /**
     * 测试程序行为的类 生产并使用身份证
     */
    public class Main {
        public static void main(String[] args) {
            Factory factory = new IDCardFactory();
            Product card1 = factory.create("小明");
            Product card2 = factory.create("小红");
            Product card3 = factory.create("小刚");
            card1.use();
            card2.use();
            card3.use();
        }
    }
    
    

    具体实现

    /**
     * 具体实现Factory所声明的抽象方法
     */
    public class IDCardFactory extends Factory{
    
        private List<Product> owners = new ArrayList<Product>();
    
        protected Product createProduct(String owner) {
            return new IDCard(owner);
        }
    
        protected void registerProduct(Product product) {
            owners.add(product);
        }
    
        public List getOwners() {
            return owners;
        }
    }
    
    /**
     * 具体实现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("使用" + owner + "的ID卡");
        }
    
        public String getOwner() {
            return owner;
        }
    }
    

    三、课后习题

    习题1:

    在示例程序中,IDCard类的构造函数并不是public,why?

    回答1:

    如果构造函数的可见性为public,那么外部类可直接使用构造函数来创建实例,而这是设计者所不希望的。
    使用构造函数的可见性为package,可以限制外部类只能通过工厂来创建实例。
    

    习题2:

    修改示例程序,为IDCard类添加卡的编号,并在IDCardFactory类中保存编号与所有者之间的对应表

    回答2:

    /**
     * 具体实现Factory所声明的抽象方法
     */
    public class IDCardFactory extends Factory{
    
        private Map<Integer, Product> database = new HashMap<Integer, Product>();
        private int serial = 100;
    
        protected synchronized Product createProduct(String owner) {
            return new IDCard(owner, serial++);
        }
    
        protected void registerProduct(Product product) {
            IDCard card = (IDCard) product;
            database.put(card.getId(), card);
        }
    }
    
    /**
     * 具体实现Product所声明的抽象方法
     */
    public class IDCard extends Product {
        private String owner;
        private int id;
    
        public IDCard(String owner, int id) {
            System.out.println("制作" + owner + "的ID卡" + id);
            this.owner = owner;
            this.id = id;
        }
    
        public void use() {
            System.out.println("使用" + owner + "的ID卡" + id);
        }
    
        public String getOwner() {
            return owner;
        }
    
        public int getId() {
            return id;
        }
    }
    

    习题3:

    为了强制往Product类的子类的构造函数中传入"产品名字"作为参数,我们采用了如下的定义方式,却出现了编译错误,why?

    public abstract class Product {
        public abstract Product(String name);
        public abstract void use();
    }
    

    回答3:

    在Java中abstract的构造函数是无法定义的。
    在Java中具体的构造函数无法被继承,无法通过父类的构造函数限制子类的构造函数。
    
  • 相关阅读:
    Android学习之三:使用DDMS调试程序
    Android学习之二:使用Android文档帮助
    Android学习之四:创建一个简单程序
    Android学习之五:android一些基本控件
    创建Android开发环境
    Android学习之七:使用Container
    Android学习之六:使用Container
    IOSresign keyboard 新法儿
    IOStxt文件UTF8、UTF16格式
    IOSXMPP arc用方法fobjcarc
  • 原文地址:https://www.cnblogs.com/zzzz76/p/14423562.html
Copyright © 2011-2022 走看看