设计模式系列原型模式
适用场景:
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