原型模式-Prototype(Java实现)

原型模式-Prototype

通过复制(克隆、拷贝)一个指定类型的对象来创建更多同类型的对象.

就像去蛋糕店买蛋糕一样. 柜台里的蛋糕都是非卖品. 只是为顾客提供一种参照. 当顾客看上某一个样式的蛋糕后. 蛋糕师就会为顾客新做一份一模一样的.

这样就可以说明为什么要有prototype模型, 而不是每次都重新new一个了.

因为每次都重新new一个的话, 代表着蛋糕要从设计到制作都要现场完成. 这时很困难的.

如果有一个原型的话. 蛋糕师就可以根据这个模板, 来参照着做出一个一模一样的. 显然这样的难度降低了很多.

卖笔和卖蛋糕的原理是一样的.本文以笔为例.

有一个管理类UnderLinePenManager, 里面有三种笔. 第一种能画波浪线, 第二种能画直线, 第三种能画虚线.

如果有人想要这三种里的某一种. 那么就根据管理类里已经注册好的模板来新建一个一样的笔出来. 

本例子中的类关系图:

类的依赖关系:

Product接口

我们将使用原型模式来创建对象, 而这些对象, 就被抽象为Product

Product还提供了复制方法createClone(). 继承了Cloneable接口.

注意: 这里的createClone()方法并不是继承于Cloneable, Cloneable里面并没有声明任何方法, Cloneable只是起标记作用的一个接口.

public interface Product extends Cloneable {
    void use(String str);

    Product createClone();
}

UnderlinePen类

这是Product接口的实现类, 下划线类. 

向特定的下划线类传入一个字符串后, 他会打印出该字符串和下划线

public class UnderLinePen implements Product {
    /**
     * 下划线字符
     */
    private char underLineChar;

    public UnderLinePen(char ch) {
        this.underLineChar = ch;
    }

    /**
     * 传入str后, 会打印str和下划线
     */
    @Override
    public void use(String str) {
        System.out.println(""" + str + """);
        System.out.print(" ");
        for (int i = 0; i < str.getBytes().length; i++) {
            System.out.print(underLineChar);
        }
        System.out.println("");
    }

    /**
     * 返回一个克隆
     */
    @Override
    public Product createClone() {
        try {
            return (Product) this.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
            return null;
        }
    }
}

UnderLinePenManager类

用于统一管理产品, 他来负责注册和克隆

public class UnderLinePenManager {
    /**
     * 各种笔注册到这里, 统一管理
     */
    private static final HashMap<String, Product> PENS = new HashMap<>();

    /**
     * 注册笔
     */
    public static void register(String name, Product pen) {
        PENS.put(name, pen);
    }

    /**
     * 从注册中心HashMap以name为key取出来一只笔, 然后克隆一个新的来返回
     */
    public static Product createPen(String name) {
        return PENS.get(name).createClone();
    }
}

Main

该类用于运行测试

public class Main {
    static {
        /**
         * 将各种笔注册到Manager来统一管理
         */
        UnderLinePenManager.register("wave-line"  , new UnderLinePen('~'));
        UnderLinePenManager.register("bee-line"   , new UnderLinePen('_'));
        UnderLinePenManager.register("dotted-line", new UnderLinePen('.'));
    }

    public static void main(String[] args) {
        // 每次需要某种笔的时候, 根据现有的笔来进行克隆一份就好了
        // 取出一只波浪线的笔
        Product anotherPen1 = UnderLinePenManager.createPen("wave-line");
        // 用波浪线的笔来打印
        anotherPen1.use("hello world");
    }
}

本例子中的代码的github地址: https://github.com/GoldArowana/design-patterns/tree/master/src/main/java/com/king/patterns/prototype

原文地址:https://www.cnblogs.com/noKing/p/java_design_patterns_Prototype.html