• Prototype


    设计模式目录

    原型模式是一种创建型设计模式, 使你能够复制已有对象, 而又无需使代码依赖它们所属的类。

    原型模式结构

    Java 的 Cloneable (可克隆) 接口就是立即可用的原型模式。

    任何类都可通过实现该接口来实现可被克隆的性质。

    java.lang.Object#clone() (类必须实现 java.lang.Cloneable 接口)

    识别方法: 原型可以简单地通过 clonecopy等方法来识别。

    样例

    在不适用标准 Cloneable接口的情况下实现原型模式

    // 基础原型。
    abstract class Shape is
        field X: int
        field Y: int
        field color: string
    
        // 常规构造函数。
        constructor Shape() is
            // ...
    
        // 原型构造函数。使用已有对象的数值来初始化一个新对象。
        constructor Shape(source: Shape) is
            this()
            this.X = source.X
            this.Y = source.Y
            this.color = source.color
    
        // clone(克隆)操作会返回一个形状子类。
        abstract method clone():Shape
    
    
    // 具体原型。克隆方法会创建一个新对象并将其传递给构造函数。直到构造函数运
    // 行完成前,它都拥有指向新克隆对象的引用。因此,任何人都无法访问未完全生
    // 成的克隆对象。这可以保持克隆结果的一致。
    class Rectangle extends Shape is
        field  int
        field height: int
    
        constructor Rectangle(source: Rectangle) is
            // 需要调用父构造函数来复制父类中定义的私有成员变量。
            super(source)
            this.width = source.width
            this.height = source.height
    
        method clone():Shape is
            return new Rectangle(this)
    
    
    class Circle extends Shape is
        field radius: int
    
        constructor Circle(source: Circle) is
            super(source)
            this.radius = source.radius
    
        method clone():Shape is
            return new Circle(this)
    
    
    // 客户端代码中的某个位置。
    class Application is
        field shapes: array of Shape
    
        constructor Application() is
            Circle circle = new Circle()
            circle.X = 10
            circle.Y = 10
            circle.radius = 20
            shapes.add(circle)
    
            Circle anotherCircle = circle.clone()
            shapes.add(anotherCircle)
            // 变量 `anotherCircle(另一个圆)`与 `circle(圆)`对象的内
            // 容完全一样。
    
            Rectangle rectangle = new Rectangle()
            rectangle.width = 10
            rectangle.height = 20
            shapes.add(rectangle)
    
        method businessLogic() is
            // 原型是很强大的东西,因为它能在不知晓对象类型的情况下生成一个与
            // 其完全相同的复制品。
            Array shapesCopy = new Array of Shapes.
    
            // 例如,我们不知晓形状数组中元素的具体类型,只知道它们都是形状。
            // 但在多态机制的帮助下,当我们在某个形状上调用 `clone(克隆)`
            // 方法时,程序会检查其所属的类并调用其中所定义的克隆方法。这样,
            // 我们将获得一个正确的复制品,而不是一组简单的形状对象。
            foreach (s in shapes) do
                shapesCopy.add(s.clone())
    
            // `shapesCopy(形状副本)`数组中包含 `shape(形状)`数组所有
            // 子元素的复制品。
    

    适用场景

    • 如果你需要复制一些对象, 同时又希望代码独立于这些对象所属的具体类, 可以使用原型模式。

      这一点考量通常出现在代码需要处理第三方代码通过接口传递过来的对象时。 即使不考虑代码耦合的情况, 你的代码也不能依赖这些对象所属的具体类, 因为你不知道它们的具体信息。

      原型模式为客户端代码提供一个通用接口, 客户端代码可通过这一接口与所有实现了克隆的对象进行交互, 它也使得客户端代码与其所克隆的对象具体类独立开来。

    • 如果子类的区别仅在于其对象的初始化方式, 那么你可以使用该模式来减少子类的数量。别人创建这些子类的目的可能是为了创建特定类型的对象。

      在原型模式中, 你可以使用一系列预生成的、 各种类型的对象作为原型。

      客户端不必根据需求对子类进行实例化, 只需找到合适的原型并对其进行克隆即可。

    原型模式的优点

    • 你可以克隆对象, 而无需与它们所属的具体类相耦合。
    • 你可以克隆预生成原型, 避免反复运行初始化代码。
    • 你可以更方便地生成复杂对象。
    • 你可以用继承以外的方式来处理复杂对象的不同配置。

    原型模式缺点

    • 克隆包含循环引用的复杂对象可能会非常麻烦。
  • 相关阅读:
    Redis 如何设置密码及验证密码?
    怎么测试 Redis 的连通性?
    Redis 的内存用完了会发生什么?
    假如 Redis 里面有 1 亿个 key,其中有 10w 个 key 是以 某个固定的已知的前缀开头的,如果将它们全部找出来?
    使用过 Redis 做异步队列么,你是怎么用的?
    简述在 MySQL 数据库中 MyISAM 和 InnoDB 的区别 ?
    你怎么看到为表格定义的所有索引?
    深入理解卷积网络的卷积
    OpenCV-Python 图像阈值 | 十五
    OpenCV-Python 图像的几何变换 | 十四
  • 原文地址:https://www.cnblogs.com/huaranmeng/p/14289732.html
Copyright © 2020-2023  润新知