设计模式——Prototype原型模式

1. 引言

Prototype原型模式是指根据实例原型、实例模型来生成新的实例。

2. 示例程序

2.1 类和接口一览表

类名说明
framewrokProduct声明抽象方法use和createClone的接口
frameworkManager调用createClone方法复制实例的类
MessageBox实现了use和createClone方法,将字符串放入方框中显示
MessageUnderline实现了use和createClone方法,将字符串下方添加一串字符显示
Main测试程序行为的类

2.2 UML图

原型模式

2.3 Product接口

use定义“使用”的方法。
createClone方法定义用于复制实例的方法。

/**
 * 继承Cloneable接口
 * @author littlemotor
 * @since  8.18
 */
public interface Printer extends Cloneable{
  
  public abstract void print();
}

2.4 Manager类

Manager并没有用到别的具体需要复制的类名,保证了与其他类之间的松耦合。

public class Manager {
  private HashMap<String, Printer> printers = new HashMap<>();
  
  public void register(String name, Printer prototype) {
    printers.put(name, prototype);
  }
  
  public Printer create(String protoname) {
    Printer p = (Product) printers.get(protoname);
    return p.clone();
  }
}

2.5 WhitePrinter类

createClone方法用于复制自己,在进行复制时,原来实例中字段的值也会被复制到新的实例中,之所以能够调用clone方法是因为父类中实现了Cloneable接口。
需要注意的是只有类自己(或他的子类)能够点用clone方法,其他类要求复制时是通过调用封装的createClone方法实现的。

/**
 * 打印白色的字
 * @author littlemotor
 * @since 18.8.18
 */

public class WhitePrinter implements Printer {
  private String content = "white";
  
  public MessageBox(String content) {
    this.content = content;
  }
  
  /**
   * 包围显示
   */
  @Override
  public void print() {
    System.out.println("白色字体:" + content);
  }

  @Override
  public Printer clone() {
    Printer p = null;
    try {
      p = (Printer)super.clone();
    } catch(CloneNotSupportedException e) {
      e.printStackTrace();
    }
    return p;
  }

}

2.6 BlackPrinter类

这个类的显示方式是在字符串下面加一行指定的字符串

public class BlackPrinter implements Printer {

  private String content = "black";
  
  public MessageUnderline(String content) {
    this.content = content;
  }
  
  @Override
  public void use() {
    System.out.println("黑色字体:" + this.content);
  }

  @Override
  public Print clone() {
    Product p = null;
    try {
      p = (Printer)super.clone();
    } catch(CloneNotSupportedException e) {
      e.printStackTrace();
    }
    return p;
  }

}

2.7 Main类

/**
 * 通过Manager类调用注册在Printer接口下方的不同类的实例 生成新的实例体会原型模式
 * 
 * @author littlemotor
 * @since 18.8.18
 */
public class Main {
  public static void main(String[] args) {
    //准备
    Manager manager = new Manager();
    Printer whitePrinter = new WhitePrinter("balabala");
    Printer blackPrinter = new BlackPrinter("balabala");
    manager.register("whitePrinter", whitePrinter);
    manager.register("blackPrinter", blackPrinter);
    //生成
    Printer blackPrinter = manager.create("blackPrinter");
    blackPrinter.print();
    Product whitePrinter = manager.create("whitePrinter");
    whitePrinter.print();
  }
}

3. 小结

在类中尽量不要出现别的类名是为了实现组件复用,以达到只有.class文件时也可以复用的目的。
在Prototype原型模式中有三个角色,分别是

3.1 Prototype(原型)

Product角色负责定义用于复制现有实例来生成新实例的方法。

3.2 ConcretePrototype(具体的原型)

ConcretePrototype负责实现复制现有实例并生成新实例的方法。

3.3 Client(使用者)

由Manager类扮演此角色,Client角色使用复制实例的方法生成新的实例。

4. 拓展——Java中的clone方法和Clonable接口

4.1 调用clone方法的基本要求

被复制对象的类或父类必须实现java.lang.Clonable接口或其子接口,则可以调用clone方法,clone方法返回值是新复制出的实例(clone方法内部的处理是分配与要复制的实例相同大小的内存空间,接着将要复制的实例中的字段的值复制到所分配的内存空间中去)

4.2 Cloneable接口

Cloneable接口被称为标记接口(marker interface),其内部并没有声明任何方法,只是用来标记“可以使用clone方法进行复制”的。

4.3 Clone方法进行的是浅复制

clone方法进行的复制只是将被复制实例的字段值直接复制到新的实例中,并没有考虑字段中所保存实例的内容,例如,当字段保存的是数组时,使用clone方法进行复制,只会复制该数组的引用,并不会一一复制数组中的元素。更详细的深拷贝与浅拷贝的区别请参阅另一篇文章。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值