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中具体的构造函数无法被继承,无法通过父类的构造函数限制子类的构造函数。
    
  • 相关阅读:
    UVA 11488 Hyper Prefix Sets (字典树)
    UVALive 3295 Counting Triangles
    POJ 2752 Seek the Name, Seek the Fame (KMP)
    UVA 11584 Partitioning by Palindromes (字符串区间dp)
    UVA 11100 The Trip, 2007 (贪心)
    JXNU暑期选拔赛
    计蒜客---N的-2进制表示
    计蒜客---线段的总长
    计蒜客---最大质因数
    JustOj 2009: P1016 (dp)
  • 原文地址:https://www.cnblogs.com/zzzz76/p/14423562.html
Copyright © 2011-2022 走看看