设计模式系列原型模式

编程

适用场景:

1、类初始化消耗资源较多

2、new 产生的一个对象需要非常繁琐的过程(数据准备、访问权限等)

3、构造函数比较复杂

原型模式创建方式分为两种:浅克隆 ,深克隆

实现方式

1、浅克隆

克隆出的新对象的引用属性内存地址还是指向原实例属性地址。即新对象与原对象引用属性共用同一内存地址,新的对象随着原实例引用属性变化而变化

Cat 接口 ,定义 clone 方法

public interface Animal {

Animal clone();

}

Cat 实现类

import java.util.List;

public class Cat implements Animal {

private Integer age;

private String name;

private List<String> ability;

public Integer getAge() {

return age;

}

public void setAge(Integer age) {

this.age = age;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public List<String> getAbility() {

return ability;

}

public void setAbility(List<String> ability) {

this.ability = ability;

}

[@Override](https://my.oschina.net/u/1162528)

public String toString() {

return "Cat{" +

"age=" + age +

", name="" + name + """ +

", ability=" + ability +

"}";

}

[@Override](https://my.oschina.net/u/1162528)

public Animal clone() {

Cat cat = new Cat();

cat.setAge(this.age);

cat.setName(this.name);

cat.setAbility(this.ability);

return cat;

}

}

模拟客户端 使用原型模式

public class Client {

public Animal startClone(Animal animal) {

return animal.clone();

}

}

Test 测试类

public class Test {

public static void main(String[] args) {

Cat cat = new Cat();

List<String> ability = new ArrayList<>();

ability.add("抓老鼠");

ability.add("抓鱼");

cat.setAge(1);

cat.setName("ketty");

cat.setAbility(ability);

Client client = new Client();

Cat catClone = (Cat) client.startClone(cat);

System.out.println(cat);

ability.add("打架");

System.out.println(cat);

System.out.println(catClone);

}

}

可以发现 ,当引用变量 ability 变化时,浅克隆后的新对象 相应属性也随之变化。

2、深克隆

克隆过程中为新对象引用属性分配新的内存地址,不会随着原实例对象引用属性的变化而变化

Dog 实现 Animal 接口,并通过字节码 序列化操作

import java.io.*;

import java.util.List;

public class Dog implements Serializable, Animal {

private Integer age;

private String name;

private List<String> ability;

public Integer getAge() {

return age;

}

public void setAge(Integer age) {

this.age = age;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public List<String> getAbility() {

return ability;

}

public void setAbility(List<String> ability) {

this.ability = ability;

}

[@Override](https://my.oschina.net/u/1162528)

public String toString() {

return "Dog{" +

"age=" + age +

", name="" + name + """ +

", ability=" + ability +

"}";

}

[@Override](https://my.oschina.net/u/1162528)

public Animal clone() {

try {

ByteArrayOutputStream bos = new ByteArrayOutputStream();

ObjectOutputStream oos = new ObjectOutputStream(bos);

oos.writeObject(this);

ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());

ObjectInputStream ois = new ObjectInputStream(bis);

Dog dog = (Dog)ois.readObject();

return dog;

} catch (IOException | ClassNotFoundException e) {

e.printStackTrace();

}

return null;

}

}

Test 测试类

public class Test {

public static void main(String[] args) {

Dog dog = new Dog();

List<String> ability = new ArrayList<>();

ability.add("看家");

dog.setName("嘟嘟");

dog.setAge(2);

dog.setAbility(ability);

Client client = new Client();

Dog dogClone = (Dog)client.startClone(dog);

System.out.println(dog);

ability.add("和主人玩耍");

System.out.println(dog);

System.out.println(dogClone);

}

}

可以发现,当原型实例引用变量ability变化时,克隆后的新对象并不会随之变化

当然在Java中,我们可以直接 实现Cloneable 接口,重写clone 方法进行克隆操作

public class Pig implements Cloneable, Serializable {

private Integer age;

private String name;

private List<String> ability;

public Integer getAge() {

return age;

}

public void setAge(Integer age) {

this.age = age;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public List<String> getAbility() {

return ability;

}

public void setAbility(List<String> ability) {

this.ability = ability;

}

[@Override](https://my.oschina.net/u/1162528)

public String toString() {

return "Dog{" +

"age=" + age +

", name="" + name + """ +

", ability=" + ability +

"}";

}

@Override

protected Object clone() throws CloneNotSupportedException {

try {

ByteArrayOutputStream bos = new ByteArrayOutputStream();

ObjectOutputStream oos = new ObjectOutputStream(bos);

oos.writeObject(this);

ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());

ObjectInputStream ois = new ObjectInputStream(bis);

Dog dog = (Dog) ois.readObject();

return dog;

} catch (IOException | ClassNotFoundException e) {

e.printStackTrace();

}

return null;

}

}

以上是 设计模式系列原型模式 的全部内容, 来源链接: utcz.com/z/516161.html

回到顶部