所以,我一直在阅读设计模式,原型模式让我困惑。我相信使用它的一个要点是避免使用 new 运算符。然后我看一下这个例子:
http://sourcemaking.com/design_patterns/prototype/java/1
首先,他们对Prototype的想法实现了一个clone()方法,这很奇怪。维基百科还说我需要一个纯子方法克隆来实现子类(为什么?)。 Java是否已经提供了这样的方法,正是我们需要它做的事情(创建一个对象的副本而不是从头开始实例化)?其次,clone方法调用运算符 new !当然这个例子是错的? (在这种情况下,我应该在其他地方学习设计模式,嘿?)。有人可以判断这种纠正是否正确吗?:
static class Tom implements Cloneable implements Xyz {
public Xyz cloan() {
return Tom.clone(); //instead of new I use clone() from Interface Cloneable
}
public String toString() {
return "ttt";
}
}
任何澄清都表示赞赏。
答案 0 :(得分:9)
原型模式的想法是有一个蓝图/模板,您可以从中生成您的实例。它不仅仅是“避免在Java中使用新的”
如果在Java中实现原型模式,则无论如何都是覆盖Object类中的现有clone()
方法,无需创建新方法。 (还需要实现Clonable接口或者你会得到异常)
举个例子:
// Student class implements Clonable
Student rookieStudentPrototype = new Student();
rookieStudentPrototype.setStatus("Rookie");
rookieStudentPrototype.setYear(1);
// By using prototype pattern here we don't need to re-set status and
// year, only the name. Status and year already copied by clone
Student tom = rookieStudentPrototype.clone();
tom.setName("Tom");
Student sarah = rookieStudentPrototype.clone();
sarah.setName("Sarah");
答案 1 :(得分:4)
设计模式只是表示软件如何以可重现的方式编写的一种方式。事实上,实现同样的事情有不同的句法方法。
因此,Prototype模式只是一种使用主副本来实现某些重写功能的方法。在Java中有几种方法可以做到这一点(我也相信其他语言)。这是一个使用'new'关键字的关键字,它基于使用接口作为实现具体类的契约。然后,单个方法采用接口的具体实现并执行相同的操作:
// software contract
interface Shape {
public void draw();
}
// concrete implementations
class Line implements Shape {
public void draw() {
System.out.println("line");
}
}
class Square implements Shape {
public void draw() {
System.out.println("square");
}
}
...
class Painting {
public static void main (String[] args) {
Shape s1 = new Line ();
Shape s2 = new Square ();
...
paint (s1);
paint (s2);
...
}
// single method executes against the software contract as a prototype
static void paint (Shape s) {
s.draw ();
}
}
您可以在http://www.javacamp.org/designPattern/prototype.html阅读更多内容或查看main Design Pattern site。信息在那里提供完整的参考。
答案 2 :(得分:3)
您链接的示例是正确的,您的代码
return Tom.clone();
将无法编译,因为clone()
不是静态方法。
克隆不是避免使用new
运算符,而是创建一个与正在克隆的对象具有相同状态(其成员字段的值)的新实例。因此,clone()
不是静态的,而是实例方法,因此您可以创建一个新实例(并使用 new 不是问题),它反映了{{1的对象的状态已被调用。
只是你的示例类(如Tom)非常简单(没有状态),clone()
方法所做的就是实例化一个 new 实例。如果它有一个更复杂的状态(比如clone()
个对象),ArrayList
方法也必须对clone()
进行深层复制。
要详细说明您的一个示例类,假设ArrayList
有一些实例状态。现在,Tom
还必须确保返回的副本与当前副本的状态匹配。
clone()
答案 3 :(得分:0)
您也可以使用BeanUtils.copyProperties方法执行Spring框架org.springframework.beans.BeanUtils提供的相同操作;
答案 4 :(得分:0)
原型实际上“没有” 将呼叫保存到new
运算符。它只是通过调用所谓的clone
来简化非敏感属性的复制。例如,
1)您有UserAccount
,该用户具有主要用户和链接的用户详细信息
2)UserAccount
的PK也称为userAccountId
。
当然,当您将所有UserAccount
对象放入一个集合中时,您希望userAccountId
是不同的。但是您仍然必须为每个链接调用new UserAccount
。否则,您最终将修改一个对象100次,并期望得到100项回报。另外,如果根据属性的敏感度将此UserAccount
作为组合(不是聚合),则可能也必须对其调用new
。
例如,如果UserAccount
具有Person
对象(并且如果'Person'具有其自己的构成),则必须调用new
以确保适当地设置了它们的引用。