图解设计模式-Prototype模式

Java开发中一般情况下通过使用new 关键字创建对象,但是有时也会在“不指定类名的前提下生成实例”的需求:
对象种类繁多,无法将它们整合到一个类中时
需要处理的对象太多,如果将它们分别作为一个类,需要编写的类文件太多。
难以根据类生成实例时
生成实例的过程太复杂,很难根据类来生成实例。
想解耦框架与生成的实例时
想让生成实例的框架不依赖与具体的类,这时就不能指定类名来生成实例,而要事先“注册”一个“原型”实例,然后通过复制该实例来生成新的实例。
 
学习根据实例来生成实例的Prototype模式。
在Java语言中可以通过clone的方式创建实例的副本。
 
实现Cloneable接口的类的实例可以调用clone方法进行复制,clone方法的返回值是复制出来的新的实例。
(clone方法内部所进行的处理是分配与要复制的实例同样大小的内存空间,接着将要复制的实例中的字段的值复制到所要分配的内存空间中去)
角色:
Prototype原型:负责定义用于复制现在实例来生成实例的方法,本示例中,Product来扮演。
ConcretePrototype具体的原型:负责实现用于复制现在实例来生成实例的方法,本示例中, MessageBox与UnderLinePen类来扮演。
client使用者:负责使用复制实例的方法生成实例,本示例中,Manager来扮演。
优点:
不用根据类来生成实例。
作为组件复用,一旦代码中出现要使用的类的名称,就无法与该类分离开来,也就无法实现复用。
 
代码:
public interface Product extends Cloneable {
    public abstract void use();
    public abstract Product createClone();
}
public class UnderLinePen implements Product {

    @Override
    public void use() {
        System.out.println("使用UnderLinePen");
    }

    @Override
    public Product createClone() {
        Product p = null;
        try {
            p = (Product) clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return p;
    }
}
public class MessageBox implements Product {

    @Override
    public void use() {
        System.out.println("使用MessageBox");
    }

    @Override
    public Product createClone() {
        Product p = null;
        try {
            p = (Product) clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return p;
    }
}
public class Manager {

    private HashMap<String,Object> registerMap = new HashMap<>();

    public void register(String className,Product product) {
        registerMap.put(className,product);
    }

    public Product create(String prototypeName) {
        Product p = (Product) registerMap.get(prototypeName);
        return p.createClone();
    }
}
public class Main {
    public static void main(String[] args) {
        Manager manager = new Manager();
        manager.register("message",new MessageBox());
        manager.register("underLine",new UnderLinePen());

        Product message = manager.create("message");
        message.use();
        Product underLine = manager.create("underLine");
        underLine.use();
    }
}
结果:
使用MessageBox
使用UnderLinePen
收藏文章数量从多到少与“把书读薄”是一个道理
原文地址:https://www.cnblogs.com/use-D/p/9576537.html