设计模式(六)之原型模式

什么是原型模式

通常,我们会使用 new something() 的方式去创建实例,但是如下几种情况可能并不支持我们这样创建。例如:

  1. 对象种类繁多,无法将他们整合到一个类中时
    需要处理的对象太多,如果将他们分别作为一个类,需要编写很多个类文件。
  2. 难以根据类生产实例
    类实例的生成过程太复杂,很难根据实例来生成实例。例如在图形编辑器中使用鼠标制作出图形的实例,在想生成一个和之前用户操作所创建出的实例完全一样的实例,会先将所创建的实例保存起来,然后通过复制来生成新的实例
  3. 想解耦框架与生产的实例
    想让生成实例的框架不依赖于具体的类。这时,不能指定类名来生成实例,而要事先注册一个原型,然后通过复制该实例来生成新的实例。

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

Cloneable接口和Clone方法

Cloneable是一个标记接口,这个接口中没有任何的抽象方法,实现该接口,表示该接口的实现类可以去使用Clone

package java.lang;

public interface Cloneable {
    
    
}

Clone方法是Object类中的一个方法,它可以在一个实例的基础上复制出一个新的实例,Object类是所有类的父类,故所有类都具有Clone方法,但是如果某个类的实例想使用此方法,该类必须先实现Cloneable接口,不然使用时会抛出CloneNotSupportedException异常。

protected native Object clone() throws CloneNotSupportedException;

Clone方法进行的是浅复制,它知识将被复制的实例的字段值直接复制到新的实例中。例如,如果字段中保存的是数组,使用Clone复制只会复制数组的引用,不会一 一复制数组中的元素。如果Clone无法满足需求可重写Clone

例子

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

Manager

package CreationPattern.PrototypeMode;

import java.util.HashMap;

/**
 * 管理并复制实例
 */

public class Manager {
    
    
    private HashMap map = new HashMap();

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

    public Product create(String protoName) {
    
    
        Product product = (Product) map.get(protoName);
        return product.createClone();
    }
}

Product

package CreationPattern.PrototypeMode;

/**
 * 产品接口
 */

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

    Product createClone();
}

MessageBox

扫描二维码关注公众号,回复: 16062194 查看本文章
package CreationPattern.PrototypeMode;

/**
 * 方框信息
 */

public class MessageBox implements Product {
    
    
    private char decoChar;

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

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

        System.out.println(decoChar + " " + s + " " + decoChar);

        for (int i = 0; i < len + 4; i++) {
    
    
            System.out.print(decoChar);
        }
        System.out.println();
    }

    @Override
    public Product createClone() {
    
    
        Product p = null;
        try {
    
    
            p = (Product) clone();
        } catch (CloneNotSupportedException e) {
    
    
            throw new RuntimeException(e);
        }
        return p;
    }
}

UnderlinePen

package CreationPattern.PrototypeMode;

/**
 * 下划线信息
 */

public class UnderlinePen implements Product {
    
    
    private char ulChar;

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

    @Override
    public void use(String s) {
    
    
        int len = s.getBytes().length;

        System.out.println("\"" + s + "\"");

        for (int i = 0; i < len; i++) {
    
    
            System.out.print(ulChar);
        }
        System.out.println();
    }

    @Override
    public Product createClone() {
    
    
        Product p = null;
        try {
    
    
            p = (Product) clone();
        } catch (CloneNotSupportedException e) {
    
    
            throw new RuntimeException(e);
        }
        return p;
    }
}

结果
在这里插入图片描述

总结

通常,我们使用 new something() 来创建实例,但是以这种方式创建是必须指定类名的,但有时候也会有在不指定类名的前提下生产实例的需求,或者对象种类繁多,又或者想解耦框架与生成实例,这时候,我们便需要使用原型模式。

猜你喜欢

转载自blog.csdn.net/weixin_43636205/article/details/129528852