设计模式-原型模式

创建型模式有五种:单例模式、工厂模式、抽象工厂模式、建造者模式、原型模式。

本次内容是最后一种创建型模式—-原型模式(Prototype Pattern)。

1、概述

原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。原型模式本质是一种克隆对象的方法,其核心是重写Object中的clone方法,调用该方法可以在内存中进行对象拷贝。

原型模式可以理解为:一个对象的产生可以不由零起步,直接从一个已经具备一定雏形的对象克隆,然后再修改为生产需要的对象。

原型模式主要包含三个角色:

抽象原型类(Prototype):定义了一个抽象的克隆方法。
具体原型类(ConcretePrototyoe):实现抽象原型类(接口)定义的克隆方法,提供一个具体的克隆方法来复制自己。
客户端(Client):使用原型类的对象来实现具体的操作,即通过复制原型对象来创建新的对象。

2、优缺点

优点:

1、性能优良,Java自带的原型模式是基于内存二进制流的拷贝,比直接new一个对象性能上提升了许多。
2、可以使用深克隆方式保存对象的状态,使用原型模式将对象赋值一份并将其状态保存起来,简化了创建对象的过程,以便在需要的时候使用(例如恢复到历史某一状态),可辅助实现撤销操作。

缺点:

1、需要为每一个类配置一个克隆方法。
2、克隆方法位于类的内部,当对已有类进行该操的时候,需要修改代码,违反了开闭原则。
3、在实现深克隆的时候需要编写较为复杂的代码,而且当对象之间存在多重嵌套引用时,为了实现深克隆,每一层对象对应的类都必须支持深克隆,实现起来会比较麻烦。因此,深拷贝、浅拷贝需要运用得当。

3、实现方式

java实现


public class Test {
    public static void main(String[] args) {
        //创建原型对象
        ConcretePrototype prototype = new ConcretePrototype();
        prototype.setAge(18);
        prototype.setName("Tom");
        System.out.println(prototype);


        //拷贝原型对象
        ConcretePrototype cloneType = prototype.clone();
        System.out.println(cloneType);

    }
}


public interface IPrototype<T> {
    T clone();
}

public class ConcretePrototype implements IPrototype {

    private int age;
    private String name;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public ConcretePrototype clone() {
        ConcretePrototype concretePrototype = new ConcretePrototype();
        concretePrototype.setAge(this.age);
        concretePrototype.setName(this.name);
        return concretePrototype;
    }

    @Override
    public String toString() {
        return "ConcretePrototype{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}

在实际编码中,JDK已经帮我们实现了一个现成的API,我们只需要实现java的Cloneable接口即可。

python实现


from copy import copy, deepcopy

class Prototype:
    def clone(self):
        pass

    def deep_clone(self):
        pass



class Customer(Prototype):
    def __init__(self):
        self.name = ''
        self.age = ''
        self.address = ''

    def set_name(self, name):
        self.name = name

    def set_age(self, age):
        self.age = age

    def set_address(self, address):
        self.address = address

    def display(self):
        print("name:", self.name)
        print("age:", self.age)
        print("address:", self.address)

    def clone(self):
        return copy(self)

    def deep_clone(self):
        return deepcopy(self)


if __name__ == '__main__':
    customer_1 = Customer()

    customer_1.set_name("AAA")
    customer_1.set_age("18")
    customer_1.set_address("XM")

    customer_2 = customer_1.clone()

    customer_1.display()
    print("------")
    customer_2.display()
    print("=============")

    customer_2.set_name("BBB")
    customer_2.set_address("FJ")
    customer_1.display()
    print("------")
    customer_2.display()
    print("=============")

    customer_3 = customer_1.clone()
    customer_3.set_name("CCC")
    customer_3.set_age("7")
    customer_1.display()
    print("------")
    customer_2.display()
    print("------")
    customer_3.display()
    print("=============")

4、应用场景

1、性能优化场景
类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等。
2、安全访问场景
当某个对象对外可能是只读的,为了防止外部对这个只读对象的修改,通常可以通过返回一个对象拷贝的形式实现只读的限制。
3、一个对象多个修改者的场景
一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用。

设计模式是一种思想,在不同的场景合理的运可以提升整体的架构的质量。不要去生搬硬套,否则将会引起过渡设计,增加维护成本。

This entry was posted in 应用, 设计模式. Bookmark the permalink.