聊聊Prototype模式吧

Prototype模式

在JAVA中通常通过new关键字生成实例。像这样使用new来生成实例时,必须指定类名。但有时需要根据现有情况下来生成新的实例。

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

    需要处理的对象太多,如果分别作为一个类,必须编写很多个类文件。

  2. 难以根据类生成实例

    生成实例的过程太复杂,很难根据类来生成实例。

  3. 解耦框架与生成的实例

    生成实例的框架不依赖具体的类。

事例程序

类和接口一览表

名字说明
Product声明抽象方法use和createClone的接口
Manager调用createClone方法复制实例的类
MessageBox实现use和createClone
UnderlinePen实现use和createClone
Main测试程序

虽然Manager类会调用createClone方法,但对拘役要复制哪一个类一无所知。不过们只要实现了product接口的类,调用它的createClone方法就可复制出新的实例。

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

类图

代码清单

Product接口

product接口是复制功能的接口,继承了java.lang.Cloneable。 ​ use方法是使用的方法,具体使用交给子类。 ​ createClone方法用于复制实例的方法。

public interface Product extends Cloneable{
​
    public abstract void use(String s);
    public abstract Product createClone();
}
复制代码

Manager类

Manager类使用product接口来复制实例。 ​ showCase保存“名字”和“实例”之间的对应关系。 ​ register会将收到的名字和product接口注册到showcase中。这里的product具体什么类型是不知道的,但有一点可以确认,它肯定是实现了product接口的类的实例。 ​ 在product和manager中没有出现messageBox和underlinePen,这就意味着魔门可以独立修改product和manager。一旦使用了别的类,就意味着该类与其他类精密的耦合在一起了。 product是连接manager与其他具体类的桥梁。

public class Manager {
    private HashMap<String, Product> showCase = new HashMap<>();
​
    public void register(String name, Product proto) {
        showCase.put(name, proto);
    }
​
    public Product create(String protoName) {
        Product product = showCase.get(protoName);
        return product.createClone();
    }
}
复制代码

MessageBox类

use使用效果如下:

***************
* Hello,world *
***************
复制代码

createClone方法用于复制自己。它内部调用的clone方法是JAVA定义的方法,用于复制自己。该类实现了Clonable接口我们才能调用这个方法,否则会抛出CloneNotSupportedException异常。因为MessageBox实现了Product,而Product继承了Clonable,所以不会抛异常。需要注意的是: Clonable本身并没有定义深任何方法,只是告诉程序可以调用clone方法。

当其它类要求复制实例时,必须调用createClone这样的方法,然后在内部调用clone方法。

@Data
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) this.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return p;
    }
}
复制代码

UnderlinePen类

use方法:

"Hello,world"
 ~~~~~~~~~~~
复制代码
@Data
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) this.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 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");
    }
}
复制代码

结果:

"Hello,world"
 ~~~~~~~~~~~
***************
* Hello,world *
***************
///
/ Hello,world /
///
复制代码

登场角色

  • 原型

    负责定义用于复制现有实例来生成新势力的方法。----product

  • 具体原型

    负责实现复制现有实例并生成新实例的方法。----MessageBox和UnderlinePen

  • 使用者

    负责使用复制方法生成新实例。----Manager

扩展

浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址。

深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值