图解设计模式(六)-Prototype模式

通过复制生成实例

new xxx()
通常情况,使用new来生成类的实例,指定类名。

需求:在 不指定类名的前提下生成实例

1)对象种类繁多,无法将它们整合到一个类中

2)难以根据类生成实例

3)想解耦框架与生成的实例

生成的实例的框架不依赖具体的类,不能指定类名来生成实例,需要“注册”一个“原型”实例,复制该实例生成新的实例。

示例

功能:将字符串放入方框中显示出来或是加上下划线显示。

Product接口和Manager接口属于框架,负责复制实例。 Manager回调用createClone方法,但它不知道复制的类是谁。实现了Product接口的类,调用createClone就能复制新的实例。

MessageBox类和UnderlinePen类是两个实现了Product接口的类。事先,需要将这两个类“注册”到Manager类中,就可以随时复制新的实例。

 

 Product接口
/**
 * 复制功能接口. 继承了Cloneable 才能在后续调用clone 本身并不实现clone方法
 * use方法是用于 使用 的方法。 使用具体由子类实现
 * createClone 方法用于复制实例的方法
 */
public interface Product extends Cloneable {
    public abstract void use(String s);

    public abstract Product createClone();
    
}

Manager接口
/**
 * Manager类 使用Product接口实现复制
 * showcase 保存实例 名字 和 实例 对应关系  使用了HashMap
 * register方法, 接收一组 名字-Product接口 注册 showcase  这里的proto是需要实现Product接口的类的实例
 * 
 * 这里Product 和 Manager 并没有出现 MessageBox和UnderlinePen 类的名字  因此可以单独修改
 * 解耦了相关的类 一旦用到了类 就是耦合了 Manager这里只用了Product这个代名词 没有具体的类名
 */
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类
/**
 * 实现Product接口
 * 定义了decochar 用于装饰字符串的字符信息
 * use方法使用 上述字符 包裹字符串信息返回
 * 
 * createClone方法用于复制自己  复制时,原来实例的字段的值也会复制到新的实例中,能调用clone的前提是实现了Cloneable接口
 * 没有实现会抛出异常,Product继承了这类 所以可以调用,但是 Cloneable接口没有定义方法
 * 
 * 只有类自己能够调用clone方法,当其他类要求复制实例是偶,必须先调用 createClone这样的方法,然后在方法内调用clone()
 */
public class MessageBox implements Product {
    private char decochar;

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

    @Override
    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("");
    }

    @Override
    public Product createClone() {
        Product p = null;
        try{
            p = (Product) clone();
        }catch (CloneNotSupportedException e){
            e.printStackTrace();
        }
        return p;
    }
}
UnderlinePen接口
/**
 * 该类ulchar字段是用来保存装饰下划线样式的字符
 * use方法 将字符串双引号放置显示  再在字符串下添加下划线
 */
public class UnderlinePen implements Product {
    private char ulchar;
    public UnderlinePen(char ulchar) {
        this.ulchar = ulchar;
    }

    @Override
    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("");
    }

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

 

public class Main {

    public static void main(String[] args) {
        Manager manager = new Manager();
        UnderlinePen upen = new UnderlinePen('~');
        MessageBox mbox = new MessageBox('*');
        MessageBox xbox = new MessageBox('/');

        manager.register("strong message", upen);
        manager.register("warning box", mbox);
        manager.register("slash box", xbox);

        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.");
    }
}
运行结果: 

"Hello, world."
 ~~~~~~~~~~~~~
*****************
* Hello, world. *
*****************
/
/ Hello, world. /
/

 

 

Prototype模式

主要解决的是 作为一个组件的形式去复用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值