对原型模式的理解

目录

  • [一、原型模式 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是抽象类),也能完成克隆。
相关推荐
努力也学不会java16 小时前
【设计模式】 原型模式
java·设计模式·原型模式
Meteors.2 天前
23种设计模式——原型模式 (Prototype Pattern)详解
设计模式·原型模式
女生也可以敲代码5 天前
JavaScript闭包、原型链、事件循环,一文彻底讲明白(小白也能懂)
开发语言·原型模式
给月亮点灯|5 天前
Vue基础知识-重要的内置关系:vc实例.__proto__.__proto__ === Vue.prototype
前端·vue.js·原型模式
心前阳光5 天前
Unity通过Object学习原型模式
学习·unity·原型模式
小凯 ོ11 天前
实战原型模式案例
java·后端·设计模式·原型模式
JuneXcy15 天前
28.原型
开发语言·javascript·原型模式
楚禾Noah16 天前
【设计模式实战】原型模式 + 工厂模式:AI Agent 配置中心
人工智能·设计模式·原型模式
找不到、了25 天前
Java设计模式之《原型模式》--深、浅copy
java·设计模式·原型模式
阿维的博客日记1 个月前
@Scope(value = WebApplicationContext.SCOPE_REQUEST)和@Scope(“prototype“)区别
原型模式