设计模式:Prototype模式

Prototype模式——通过复制生成实例

在Java中,我们通常使用new关键字指定类名来生成类的实例。但是在开发过程中,我们有时也会遇到“在不指定类名的前提下生成实例”的需求。

这里我们采用根据实例来生成新实例的Prototype模式。通过clone方法的Cloneable接口的使用来创建出实例的副本。

下面这段示例程序的功能是将字符串放入方框中显示出来或是加上下划线显示出来。

  • 类和接口的一览表
名字说明
frameworkProduct声明了抽象方法use和createClone的接口
frameworkManager调用createClone方法复制实例的类
defaultMessageBox将字符串放入方框中并使其显示出来的类。实现了use和createClone方法
defaultUnderlinePen将字符串加上下划线并使其显示出来的类。实现了use和createClone方法
defaultMain测试程序行为的类
  • framework包

  • Product接口

package framework;

public interface Product extends Cloneable {
    public abstract void use(String s);

    public abstract Product createClone();
}
  • Manager类
package framework;

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类
import framework.Product;

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类
import framework.Product;

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类
import framework.Manager;
import framework.Product;

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. /
/

##Prototype模式中的角色

  • Prototype(原型)

Product角色负责定义用于复制现有实例来生成新实例的方法。在示例程序中,由Product接口扮演此角色。

  • ConcretePrototype(具体的原型)

ConcretePrototype角色负责实现复制现有实例并生成新实例的方法。在示例程序中,由MessageBox类的UnderlinePen类扮演此角色。

  • Client(使用者)

Client角色负责使用复制实例的方法生成新的实例。在示例程序中,由Manager类扮演此角色。


##Prototype模式的思路

既然要创建新的实例,为什么使用Prototype模式而不是直接使用new关键字?

  • 对象种类繁多,无法将它们整个到一个类中时

在本例中使用了3种样式,但是如果为每一种样式编写一个类,类的数量将会非常庞大,源程序的管理也会变得非常困难。

  • 难以根据类生成实例时

如果根据类生成实例很困难时,用实例生成实例可能会要简单很多。

  • 想解耦框架与生成的实例时

在Manager类的create()方法中,我们并没有使用类名,而是使用“strong message”等字符串为生成的实例命名。这种方式具有更好的通用性,而且将框架从类名的束缚中解脱出来了。


想了解更多关于设计模式:设计模式专栏
设计模式总结

相关推荐
©️2020 CSDN 皮肤主题: 终极编程指南 设计师:CSDN官方博客 返回首页