目录

对原型模式的理解

目录

  • [一、原型模式 vs. 传统的复制对象](#一、原型模式 vs. 传统的复制对象)
    • 1、传统的复制对象
    • 2、原型模式
      • [2.1 原型模式是什么?](#2.1 原型模式是什么?)
      • [2.2 如何实现呢?(原型模式的思想)](#2.2 如何实现呢?(原型模式的思想))
      • [2.3 对原型的理解](#2.3 对原型的理解)
      • [2.4 示例](#2.4 示例)
        • [2.4.1 示例1:Java 的 Cloneable (可克隆) 接口就是立即可用的原型模式](#2.4.1 示例1:Java 的 Cloneable (可克隆) 接口就是立即可用的原型模式)
        • [2.4.2 示例2:克隆时,用户没传入具体的类](#2.4.2 示例2:克隆时,用户没传入具体的类)

一、原型模式 vs. 传统的复制对象

  • 第一次看到原型模式这个名字时,我是懵逼的。这是啥意思啊?
  • 看了相关介绍后,我更懵逼了,这原型模式不就是复制对象吗?这也能算一种设计模式?

1、传统的复制对象

  • 传统的复制对象:必须new一个属于相同类的对象。 然后,必须遍历原始对象的所有成员变量, 并将成员变量值复制到新对象中。
java 复制代码
// 示例
public class User {
    @Getter
    @Setter
    private String name;

    @Setter
    private String ak;

    @Setter
    @Getter
    private String sk;
}

public class UserService {
    public void doProcess(User user) {
        // 要求拷贝user
        User copyedUser = new User();

        copyedUser.setName(user.getName());
        copyedUser.setSk(user.getSk());
//        copyedUser.setAk(user.getAk()); // 错误
    }
}
  • 这里有个小问题: 有些对象可能拥有私有成员变量, 它们在对象本身以外是不可见的(如User的ak字段)。
  • 传统的复制还有另外一个问题必须知道对象所属的类才能创建复制品, 所以代码必须依赖该类
  • 还可能有另外一个问题: 有时只知道对象所实现的接口, 而不知道其所属的具体类, 比如向方法的某个参数传入实现了某个接口的任何对象。
java 复制代码
public void execute(IBuy user) {
        
}

2、原型模式

2.1 原型模式是什么?

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

2.2 如何实现呢?(原型模式的思想)

  • 原型模式将克隆过程委派给被克隆的实际对象(让传入的对象自身具有克隆能力,调用该对象的克隆(clone)方法,即可完成克隆)。
    • 在clone方法中,(1)由于知道自己所属的类,自然可以轻轻松松new一个当前类的对象。(2)由于类中的方法也能访问自己的私有成员变量,因此,可以毫无阻力的将原始对象所有的成员变量值复制到新建对象中。【原型模式解决了传统复制对象的3个问题

2.3 对原型的理解

  • 原型 并不是计算机的独有概念,而是生活中的常见概念。当一个产品原型被验证是成功的,后续会被大量复制,并被销售到全国。因此,原型的本质就是被复制。
    • 支持克隆(被复制)的对象即为原型。

2.4 示例

2.4.1 示例1:Java 的 Cloneable (可克隆) 接口就是立即可用的原型模式
java 复制代码
@ToString
public class User implements Cloneable {
    @Getter
    @Setter
    private String name;

    @Setter
    private String ak;

    @Setter
    @Getter
    private String sk;

    @Override
    public User clone() {
        try {
            return (User) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
        }
    }
}

public class Application {
    public static void main(String[] args) {
        User user = new User();
        user.setName("张三");
        user.setAk("123456");
        user.setSk("654321");

        User clonedUser = user.clone();
        System.out.println(clonedUser);
    }
}

/**
User(name=张三, ak=123456, sk=654321)
*/
  • Cloneable仅仅是一个用于标识的接口,里面啥都没有。
java 复制代码
public interface Cloneable {
}
  • Object提供了clone方法
java 复制代码
protected native Object clone() throws CloneNotSupportedException;
  • 一个类想用Object的clone()方法,那么就必须实现Cloneable接口,否则会抛异常:CloneNotSupportedException。
2.4.2 示例2:克隆时,用户没传入具体的类
java 复制代码
public abstract class Shape implements Cloneable {
    @Override
    public Shape clone() throws CloneNotSupportedException {
        return (Shape) super.clone();
    }
}

@Data
public class Circle extends Shape {
    /**
     * 半径
     */
    private int radius;
}

@Data
public class Rectangle extends Shape {
    private int width;
    private int height;
}

public class Application {
    public static void main(String[] args) {
        Circle circle = new Circle();
        circle.setRadius(10);

        Rectangle rectangle = new Rectangle();
        rectangle.setHeight(15);
        rectangle.setWidth(5);

        List<Shape> shapes = new ArrayList<>();
        shapes.add(circle);
        shapes.add(rectangle);

        shapes.stream().forEach(shape -> {
            try {
                Shape clonedShape = shape.clone();
                System.out.println(clonedShape);
            } catch (CloneNotSupportedException e) {
                throw new RuntimeException(e);
            }
        });
    }
}
  • 即使没传入具体的类(Shape是抽象类),也能完成克隆。
本文是转载文章,点击查看原文
如有侵权,请联系 xyy@jishuzhan.net 删除
相关推荐
Yvette-W2 天前
【JavaScript】原型链 prototype 和 this 关键字的练习(老虎机)
开发语言·前端·javascript·ecmascript·原型模式
阿湯哥2 天前
Kettle如何与应用集成
原型模式
程序员沉梦听雨3 天前
原型模式详解
设计模式·原型模式
编程侦探5 天前
【设计模式】原型模式:用“克隆”术让对象创建更灵活
c++·设计模式·原型模式
此木|西贝6 天前
【设计模式】原型模式
java·设计模式·原型模式
云徒川7 天前
【设计模式】原型模式
java·设计模式·原型模式
QTX187307 天前
JavaScript 中的原型链与继承
开发语言·javascript·原型模式
暮乘白帝过重山7 天前
Singleton和Prototype的作用域与饿汉式/懒汉式的初始化方式
spring·原型模式·prototype·饿汉式·singleton·懒汉式
绝顶少年7 天前
Component 与 Bean 的深度解析:详细讲解Component和bean的异同以及与其搭配使用的其他注解及其使用场景
原型模式
nlog3n8 天前
Java 原型模式 详解
java·开发语言·原型模式