1、设计模式 (五)原型模式(Prototype) 原型模式就是通过一个原型对象来表明要创建的对象类型,然后用复制这个原型对象的方法来创建更多同类型的对象。 自己对原型模式简单理解的原理图如下: 具体属性没有添加: 原型模式里面关键点就在一个Cloneable接口和clone方法的重写 下面就通过一个配钥匙的例子简单的写了一个程序,起初一个一个抽象类,这样可以重写clone方法,如果是接口的话就得到子类里面把重写的方法具体声明,这样的话对于程序的复用性不是很好,于是就写了一个抽象的类KeyPrototype然后,写了两个子类继承一个客户端,代码如下: [java] view pla
2、incopy 1. package com.designpattern.prototype; 2. 3. public abstract class KeyPrototype implements Cloneable { 4. private String color; 5. private float length; 6. private float thick; 7. 8. @Override 9. protected Object clone() throws CloneNotSupported
3、Exception { 10. return super.clone(); 11. } 12. 13. @Override 14. public String toString() { 15. return this.getClass() + " -> Color:" + this.getColor() + " Length:" 16. + this.getLength() + " Thick:" + this.getThick(); 17. }
4、 18. 19. public String getColor() { 20. return color; 21. } 22. 23. public float getLength() { 24. return length; 25. } 26. 27. public float getThick() { 28. return thick; 29. } 30. 31. public void setCol
5、or(String color) { 32. this.color = color; 33. } 34. 35. public void setLength(float length) { 36. this.length = length; 37. } 38. 39. public void setThick(float thick) { 40. this.thick = thick; 41. } 42. 43. } [
6、java] view plaincopy 1. package com.designpattern.prototype; 2. 3. public class CopperKey extends KeyPrototype { 4. 5. } [java] view plaincopy 1. package com.designpattern.prototype; 2. 3. public class AluminiumKey extends KeyPrototype { 4. 5. } [java] vie
7、w plaincopy 1. package com.designpattern.prototype; 2. 3. public class Client { 4. public static void main(String[] args) { 5. KeyPrototype copperkey = new CopperKey(); 6. copperkey.setColor("red"); 7. copperkey.setLength(12); 8. copperkey.s
8、etThick(2); 9. System.out.println(copperkey); 10. 11. try { 12. KeyPrototype aluminaumkey = (KeyPrototype) copperkey.clone(); 13. aluminaumkey.setColor("yellow"); 14. aluminaumkey.setLength(10); 15. aluminaumkey.se
9、tThick(5); 16. System.out.println(aluminaumkey); 17. } catch (CloneNotSupportedException e) { 18. e.printStackTrace(); 19. } 20. } 21. } [html] view plaincopy 1. class com.designpattern.prototype.CopperKey -> Color:red Length:12.0 T
10、hick:2.0 2. class com.designpattern.prototype.CopperKey -> Color:yellow Length:10.0 Thick:5.0 这样就简单对前者进行的复制,很显然他们并不是一个对象,里面关于clone的东西做了一个简单的总结 同时来证明他们确实是两个对象,就是改动里面的属性不互相影响: 首先我创建了一个Dog类 [java] view plaincopy 1. package com.note.clone; 2. 3. public class Dog/* implements Cloneable
11、/{ 4. private String color; 5. private String name; 6. public Dog(String name,String color){ 7. this.name = name; 8. this.color = color; 9. } 10. 11. public String getColor() { 12. return color; 13. } 14. 15.
12、public void setColor(String color) { 16. this.color = color; 17. } 18. 19. public String getName() { 20. return name; 21. } 22. 23. public void setName(String name) { 24. this.name = name; 25. } 26. 27. /* @Override
13、 28. protected Object clone() throws CloneNotSupportedException { 29. // TODO Auto-generated method stub 30. return super.clone(); 31. }*/ 32. 33. @Override 34. public String toString() { 35. return this.getClass()+" "+this.getName()+" "+th
14、is.getColor(); 36. } 37. 38. 39. } 然后写了一个Tom类,其中Tom类里面有私有属性Dog [java] view plaincopy 1. package com.note.clone; 2. 3. public class Tom implements Cloneable { 4. private String color; 5. private Dog dog = new Dog("mimi", "yellow");; 6. priv
15、ate String name; 7. 8. @Override 9. protected Object clone() throws CloneNotSupportedException { 10. Tom o = null; 11. o = (Tom)super.clone(); 12. // o.setDog((Dog)o.getDog().clone()); 13. return o; 14. } 15. 16. public Str
16、ing getColor() { 17. return color; 18. } 19. 20. public Dog getDog() { 21. return dog; 22. } 23. 24. public String getName() { 25. return name; 26. } 27. 28. public void setColor(String color) { 29. thi
17、s.color = color; 30. } 31. 32. public void setDog(Dog dog) { 33. this.dog = dog; 34. } 35. 36. public void setName(String name) { 37. this.name = name; 38. } 39. 40. @Override 41. public String toString() { 42.
18、 return this.getClass() + " " + this.getName() + " " + this.getColor() 43. + "\n" + "Dog:" + this.dog; 44. } 45. 46. } 然后写了一个People类简单的对上述的两个程序进行测试: [java] view plaincopy 1. package com.note.clone; 2. 3. public class People { 4. 5. public
19、 static void main(String[] args) { 6. Tom tom = new Tom(); 7. tom.setName("Tom"); 8. tom.setColor("blue"); 9. System.out.println(tom); 10. System.out.println(); 11. 12. try { 13. Tom tylo = (Tom) tom.clone()
20、 14. tylo.setName("tylo"); 15. tylo.setColor("red"); 16. tylo.getDog().setName("lucky"); 17. tylo.getDog().setColor("green"); 18. System.out.println(tylo); 19. System.out.println(); 20. System.o
21、ut.println(tom); 21. System.out.println(); 22. 23. Dog dog = tylo.getDog(); 24. dog.setName("hello"); 25. dog.setColor("white"); 26. System.out.println(tylo); 27. System.out.println(); 28. Sy
22、stem.out.println(tom); 29. System.out.println(); 30. 31. } catch (CloneNotSupportedException e) { 32. e.printStackTrace(); 33. } 34. 35. } 36. } 运行结果如下: [html] view plaincopy 1. class com.note.clone.Tom Tom blue 2. Dog:c
23、lass com.note.clone.Dog mimi yellow 3. 4. class com.note.clone.Tom tylo red 5. Dog:class com.note.clone.Dog lucky green 6. 7. class com.note.clone.Tom Tom blue 8. Dog:class com.note.clone.Dog lucky green 9. 10. class com.note.clone.Tom tylo red 11. Dog:class com.note.cl
24、one.Dog hello white 12. 13. class com.note.clone.Tom Tom blue 14. Dog:class com.note.clone.Dog hello white 这样很明确的表明了对于这两个对象的属性,自己的属性除了Dog以外都是自己的,没有对着对方的属性的改变而改变,但是Dog属性,两个对象的属性是一样的 那么这里就到了深度克隆 我们把Dog和Tom里注释掉的内容打开再运行People程序,运行结果如下: [html] view plaincopy 1. class com.note.clone.Tom
25、 Tom blue 2. Dog:class com.note.clone.Dog mimi yellow 3. 4. class com.note.clone.Tom tylo red 5. Dog:class com.note.clone.Dog lucky green 6. 7. class com.note.clone.Tom Tom blue 8. Dog:class com.note.clone.Dog mimi yellow 9. 10. class com.note.clone.Tom tylo red 11.
26、Dog:class com.note.clone.Dog hello white 12. 13. class com.note.clone.Tom Tom blue 14. Dog:class com.note.clone.Dog mimi yellow 很明显发现,两个对象的Dog属性也没有互相影响,说明了他们不是用的一个引用,这样也证明了上面的例子,他们分别是一个对象,达到了克隆复用的应用。 在原型模式中,可以动态的添加产品分类,而且对整体结构没有影响。 由于原型模式需要给每一个类都配备一个克隆方法,这就需要在这几类的时候通盘考虑,因为在已有类的基础上来添加clone操作时比较困难的,而且原型模式在实现深层的复制时,需要编写一定量的代码。 本文转自csdn:






