首页 > 代码库 > (五)(创建型模式)原型模式
(五)(创建型模式)原型模式
一、原型模式(prototype pattern):
使用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。原型模式是一种对象创建型模式。
二、应用场景:
对象的创建非常复杂,可以使用原型模式快捷的创建对象。在运行过程中不知道对象的具体类型,可使用原型模式创建一个相同类型的对象,或者在运行过程中动态的获取到一个对象的状态。
三、应用实例:
动物界的掌控者Tom,想要再建造一辆奥迪车,但是再去生产比较麻烦,有没有别的方法快速获取呢?
四、方案:
UML图:
代码1:
package com.yq.test; /** * Created by yq on 2016/11/23. */ public class Audi implements Cloneable { public Audi() { System.out.println("Audi构造ing..."); } private String model = "奥迪"; private String tire = "米其林"; private String door = "单门"; private Engine engine = new Engine("A6"); @Override public Audi clone() { Object object = null; try { object = super.clone(); } catch (CloneNotSupportedException e) { throw new RuntimeException(e); } return (Audi) object; } @Override public String toString() { return "Audi{" + "model=‘" + model + ‘\‘‘ + ", tire=‘" + tire + ‘\‘‘ + ", door=‘" + door + ‘\‘‘ + ", engine=‘" + engine.toString() + ‘\‘‘ + ‘}‘; } }
可复制的原型类-奥迪车
package com.yq.test; /** * Created by yq on 2016/11/23. */ public class Engine { public Engine(String str) { System.out.println(str + "引擎构造中ing..."); } }
原型类成员对象-引擎
package com.yq.test; /** * Created by yq on 2016/11/23. */ public class client { public static void main(String[] args) { Audi audi = new Audi(); System.out.println("实例对象 hashCode:" + audi.hashCode()); System.out.println(audi.toString()); Audi au = audi.clone(); System.out.println("复制对象 hashCode:" + au.hashCode()); System.out.println(au.toString()); } } //output A6引擎构造中ing... Audi构造ing... 实例对象 hashCode:1956725890 Audi{model=‘奥迪‘, tire=‘米其林‘, door=‘单门‘, engine=‘com.yq.test.Engine@1540e19d‘} 复制对象 hashCode:1735600054 Audi{model=‘奥迪‘, tire=‘米其林‘, door=‘单门‘, engine=‘com.yq.test.Engine@1540e19d‘}
客户端调用-复制奥迪车
分析:从代码1中输出可以看出,复制奥迪车时,没有构造引擎,也没有构造Audi,所以只是完整的复制了一个对象属性,对应的hashCode不等,说明是复制得到了一个新的对象。
但是注意到原型对象和复制的新对象,他们的属性中引擎对象指向的是同一个引用,这当然不是我们想要的。
这是因为对于clone方法,它执行的是浅拷贝,也就是说如果是引用类型的属性,则它不会进行拷贝,而是只拷贝引用。
代码2:
package com.yq.test; /** * Created by yq on 2016/11/23. */ public class Audi implements Cloneable { private String model = "奥迪"; private String tire = "米其林"; private String door = "单门"; private AudiEngine engine = new AudiEngine("A6"); public Audi() { System.out.println("Audi构造ing..."); } @Override public Audi clone() { Object object = null; try { object = super.clone(); ((Audi)object).engine=engine.clone(); } catch (CloneNotSupportedException e) { throw new RuntimeException(e); } return (Audi) object; } @Override public String toString() { return "Audi{" + "model=‘" + model + ‘\‘‘ + ", tire=‘" + tire + ‘\‘‘ + ", door=‘" + door + ‘\‘‘ + ", engine=‘" + engine.toString() + ‘\‘‘ + ‘}‘; } }
可复制的原型类-奥迪车
package com.yq.test; /** * Created by yq on 2016/11/23. */ public class AudiEngine implements Cloneable { public AudiEngine(String str) { System.out.println(str + "引擎构造中ing..."); } @Override public AudiEngine clone() { System.out.println("Engine clone() 调用ing..."); Object object = null; try { object = super.clone(); } catch (CloneNotSupportedException e) { throw new RuntimeException(e); } return (AudiEngine) object; } }
原型类成员对象-引擎
package com.yq.test; /** * Created by yq on 2016/11/23. */ public class client { public static void main(String[] args) { Audi audi = new Audi(); System.out.println("实例对象 hashCode:" + audi.hashCode()); System.out.println(audi.toString()); Audi au = audi.clone(); System.out.println("复制对象 hashCode:" + au.hashCode()); System.out.println(au.toString()); } } //output A6引擎构造中ing... Audi构造ing... 实例对象 hashCode:1956725890 Audi{model=‘奥迪‘, tire=‘米其林‘, door=‘单门‘, engine=‘com.yq.test.AudiEngine@1540e19d‘} Engine clone() 调用ing... 复制对象 hashCode:1735600054 Audi{model=‘奥迪‘, tire=‘米其林‘, door=‘单门‘, engine=‘com.yq.test.AudiEngine@14ae5a5‘}
客户端调用-复制奥迪车
分析:代码2实现了深拷贝,在Audi类的clone()方法中,指定了引用对象的拷贝,并在Engine类中也继承了cloneable,成功调用,从结果看出,Audi对象是新对象,新对象的Engine引用对象也是新对象,并且复制时都没有调用构造器。
备注:深拷贝,需要对指定实例的每个对象都指定拷贝,并且每个引用对象都要实现clone(),有比较大的代码量。
原型模式是跨权限的,所以和单例模式冲突。
以上内容,纯属个人见解,如有错误,望不吝指正。
(五)(创建型模式)原型模式