资源描述
设计模式 (五)原型模式(Prototype)
原型模式就是通过一个原型对象来表明要创建的对象类型,然后用复制这个原型对象的方法来创建更多同类型的对象。
自己对原型模式简单理解的原理图如下:
具体属性没有添加:
原型模式里面关键点就在一个Cloneable接口和clone方法的重写
下面就通过一个配钥匙的例子简单的写了一个程序,起初一个一个抽象类,这样可以重写clone方法,如果是接口的话就得到子类里面把重写的方法具体声明,这样的话对于程序的复用性不是很好,于是就写了一个抽象的类KeyPrototype然后,写了两个子类继承一个客户端,代码如下:
[java] view plaincopy
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 CloneNotSupportedException {
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. }
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 setColor(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. }
[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] view 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.setThick(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.setThick(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 Thick: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 */{
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. 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
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()+" "+this.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. private 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 String 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. this.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. 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 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();
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.out.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. System.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: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 lucky green
9.
10. class com.note.clone.Tom tylo red
11. Dog:class com.note.clone.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 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. 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:
展开阅读全文