大白话原型模式(Prototype Pattern)

大白话原型模式(Prototype Pattern)

意图

原型模式是创建型设计模式,可以复制已存在的对象而无需依赖它的类。

问题

假如现在有一个对象,我们想完全复制一份新的,我们该如何做?

  1. 创建同一个类的新对象
  2. 遍历所有已存在对象的值,然后将他们的值复制到新对象。

很好,但是我们会发现存在如下问题:

  1. 该对象的值并不一定全对对外开放,比如Java中的private,外部无法访问。
  2. 使用这种办法必须知道该对象所属的类而且依赖这个类。
  3. 有些时候我们只知道该对象实现的接口,而不是具体的实现类。

解决

这个时候我们就需要原型模式。原型模式将克隆过程委托给被克隆的对象。该模式为所有支持克隆的对象声明一个公共接口,这个接口允许克隆一个对象,而不必将代码和该对象的类耦合。通常,这样的接口只包含一个克隆方法。

克隆方法的实现在所有类中都非常相似。该方法创建当前类的一个对象,并将旧对象的所有字段值转移到新对象中。这样就可以复制私有字段,因为大多数编程语言都允许对象访问属于同一类的私有字段。

结构

原型模式类图

原型模式包含如下角色

  • Prototype:它是声明克隆方法的接口,是所有具体原型类的公共父类,可以是抽象类也可以是接口,甚至还可以是具体实现类。
  • ConcretePrototype:它实现在抽象原型类中声明的克隆方法,在克隆方法中返回自己的一个克隆对象

实例

在Java中,所有的类都继承了java.lang.Object。Object提供了clone方法能实现Java对象复制。
我们只需注意两点即可。

  1. 实现克隆的Java类必须实现一个标识接口Cloneable,表示这个Java类支持被复制。如果没有实现这个接口但调用了clone()方法,Java编译器将抛出一个CloneNotSupportedException异常。
  2. 浅克隆和深克隆
    java的clone函数只是“浅克隆”,也就是仅对变量值做复制。如果是引用变量,其内容指向的内存地址是不变的。

参考文献

https://refactoring.guru/design-patterns/prototype

Java状态机模式可以想象成一个自动售货机。这个售货机有不同的状态,比如“等待投币”“已投币”等。在不同的状态下,售货机对顾客的操作会有不同的反应。 就像在“等待投币”状态时,顾客投币,售货机就会进入“已投币”状态;但如果顾客此时按出货按钮,售货机就不会出货,因为还没投币。当处于“已投币”状态时,顾客再投币,售货机可能会提示“已投币,无需再投”,而按出货按钮,售货机就会出货,然后回到“等待投币”状态。 在Java里,要实现这个状态机模式,首先得定义一个状态接口,就像引用[1]里的 `VendingMachineState` 接口,它包含了在不同状态下售货机的行为,比如 `insertCoin()`(投币)和 `dispenseItem()`(出货)。然后为每个状态创建具体的类来实现这个接口,在具体的类里实现对应状态下的行为逻辑。 ```java // 状态接口 public interface VendingMachineState { void insertCoin(); void dispenseItem(); } // 等待投币状态 class WaitingForCoinState implements VendingMachineState { @Override public void insertCoin() { System.out.println("已投币,进入可出货状态"); // 这里可以添加状态切换的逻辑 } @Override public void dispenseItem() { System.out.println("未投币,无法出货"); } } // 已投币状态 class CoinInsertedState implements VendingMachineState { @Override public void insertCoin() { System.out.println("已投币,无需再投"); } @Override public void dispenseItem() { System.out.println("出货中..."); // 这里可以添加状态切换回等待投币状态的逻辑 } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值