图解设计模式--Prototype(原型模式)

通过复制生成实例

Prototype模式

在一些情况下,我们需要根据现有的实例来生成新的实例。比如:

  1. 对象种类繁多,无法将它们整合到一个类中时
  2. 难以根据类生成实例时
  3. 想解耦框架与生成的实例时

在设计模式中,Prototype模式是指根据实例原型、实例模型来生成新的实例。

示例程序

Product.java

package prototype;

public interface Product extends Cloneable {

    public abstract void use(String s);
    public abstract Product createClone();

}

Manager.java

package prototype;

import java.util.HashMap;

public class Manager {

    private HashMap showcase = new HashMap();

    public void register(String name, Product proto) {
        showcase.put(name, proto);
    }

    public Product create(String protoname) {
        Product p = (Product) showcase.get(protoname);
        return p.createClone();
    }
}

MessageBox.java

package prototype;

public class MessageBox implements Product {

    private char decochar;

    public MessageBox(char decochar) {
        this.decochar = decochar;
    }

    public void use(String s) {
        int length = s.getBytes().length;
        for (int i = 0; i < length + 4; i++) {
            System.out.print(decochar);
        }
        System.out.println("");
        System.out.println(decochar + " " + s + " " + decochar);
        for (int i = 0; i < length + 4; i++) {
            System.out.print(decochar);
        }
        System.out.println("");
    }

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

UnderlinePen.java

package prototype;

public class UnderlinePen implements Product{
    private char ulchar;

    public UnderlinePen(char ulchar) {
        this.ulchar = ulchar;
    }

    public void use(String s) {
        int length = s.getBytes().length;
        System.out.println("\"" + s + "\"");
        System.out.print(" ");
        for (int i = 0; i < length; i++) {
            System.out.print(ulchar);
        }
        System.out.println("");
    }

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

Main.java

package prototype;

public class Main {

    public static void main(String[] args) {
        // 准备
        Manager manager = new Manager();
        UnderlinePen upen = new UnderlinePen('~');
        MessageBox mbox = new MessageBox('*');
        MessageBox sbox = new MessageBox('/');
        manager.register("strong message", upen);
        manager.register("warning box", mbox);
        manager.register("slash box", sbox);

        // 生成
        Product p1 = manager.create("strong message");
        p1.use("Hello, world.");
        Product p2 = manager.create("warning box");
        p2.use("Hello, world.");
        Product p3 = manager.create("slash box");
        p3.use("Hello, world.");
    }
}

Prototype模式中的角色

  1. Prototype(原型)

    Product 角色负责定义用户复制现有实例来生成新实例的方法。示例程序中的 Product 接口。

  2. ConcretePrototype(具体的原型)

    ConcretePrototype角色负责实现复制现有实例并生成新实例的方法。示例程序中的MessageBox类和 UnderlinePen 类。

  3. Client(使用者)

    Client角色负责用复制实例的方法生成新的实例。实例程序中的 Manager 类。

拓展思路

Q:类名是束缚么?

A: 一旦在代码中出现要使用的类的名字,就无法与该类分离开来,也就无法实现复用。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容