“如果”语句与 OO 设计 - 2
我遇到了类似的问题 “if”语句与 OO Design - 1 但略有不同。这是打开列表框的 onValueChange 弹出窗口(不同对象/弹出窗口)的问题
Popup1 p1; // different objects
Popup2 p2; // different objects
Popup3 p3;
...
listbox.add("p1");
listbox.add("p2");
listbox.add("p3");
...
listbox.addChangeHandler() {
if(getSelectedItem().equals("p1")){
p1 = new Popup1();
p1.show();
} else if() {...}
....
}
我不想写“if” if p1 then p1 = new Popup1(); p1.center();
我该如何处理这种情况?有什么设计模式吗?
这是我的解决方案,但成本太高,
map() {
map.put("p1", new Popup1());
map.put("p2", new Popup2());
map.put("p3", new Popup3());
}
onValueChange() {
map.get(selectedItem).show();
}
一个缺点是初始化所有弹出窗口。但仅当 valueChange 时才需要
I encountered similar problem “if” statement vs OO Design - 1 but it is slightly different. Here is the problem that open the popup (different objects/popups) onValueChange of listbox
Popup1 p1; // different objects
Popup2 p2; // different objects
Popup3 p3;
...
listbox.add("p1");
listbox.add("p2");
listbox.add("p3");
...
listbox.addChangeHandler() {
if(getSelectedItem().equals("p1")){
p1 = new Popup1();
p1.show();
} else if() {...}
....
}
I don't want to write "if" that if p1 then p1 = new Popup1(); p1.center();
How I can handle this situation? Any design-pattern?
Here is my solution but it is so costly
map() {
map.put("p1", new Popup1());
map.put("p2", new Popup2());
map.put("p3", new Popup3());
}
onValueChange() {
map.get(selectedItem).show();
}
One drawback is initialization all the popups. but it is require only when valueChange
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
好吧,如果 P1 和 P2 都实现相同的接口,那么
你可以简单地做
Well, if P1 and P2 both implement the same interface, i.e
then you could simply do
我同意尽可能利用公共基类,但您不能总是为可能需要在不同子类之间进行选择的每种用法向基类添加方法。
对于选择逻辑特定于一段代码的情况(例如将用户操作与对象(例如弹出窗口)匹配,并且您无法找到利用公共基类的方法),您的“地图”解决方案是一种不错的方法。
您应该推迟实例化直到您需要它为止:
匿名类是无状态的,因此如果您想提高效率,您可以创建匿名实例一次并重用它们。
I agree with leveraging the common base class when you can, but you can't always add a method to the base class for every usage that might call for selecting between different subclasses.
Your "map" solution is a decent approach for cases where the selection logic is specific to a piece of code, like matching user action to an object (e.g. popup), and you can't find a way to leverage the common base class.
You should defer the instantiation until you need it:
The anonymous classes are stateless, so if you wanted to be extra efficient, you could create the anonymous instances once and reuse them.
是的,这种设计模式叫做多态性。您为所有 PopupX 类定义一个超类。在这个超类中,您定义了一个方法“onChange”。然后你在每个子类中实现这个方法。当您选择一个项目时,您可以定义超类对象的引用并调用“onChange”。
Yes, this design pattern is called polymorphism. You define a super class for all your PopupX classes. In this super class you define a method "onChange". Then you realize this method in each subclass. When you select an item, you define a reference on the superclass object and call "onChange".
如果确实存在三个不同的类 Popup1、Popup2、Popup3,那么它们应该继承一个公共基类(大概称为 Popup)或实现一个公共接口(如已经建议的那样)。但看来您需要一种方法将标识弹出窗口的字符串映射到弹出对象。听起来像是工厂模式的一个机会,它看起来像这样。
然后会像这样使用:
If there really are three different classes Popup1, Popup2, Popup3, then they should either inherit from a common base class (presumably called Popup) or implement a common interface (as already suggested). But it appears you need a way to map strings identifying popups to popup objects. Sounds like an opportunity for factory pattern, which would look something like this.
And then would be used like:
你的“昂贵”解决方案对我来说似乎很好。更好的是,您可以从地图中填充列表框,因此:
当然,您可能希望键按特定顺序排列,在这种情况下,首先将它们添加到排序列表中。
Your "costly" solution seems just fine to me. Better yet, from your map you can populate the listbox, thus:
Of course you may want the keys in a particular order, in which case first add them to a sorted list.
不幸的是,鉴于限制,没有办法解决你提到的问题。
如果弹出窗口仅略有不同,则可以将它们实现为 1 个类,并具有定义弹出窗口类型的属性。
否则,最好将其封装在像@JST提到的工厂类中,这样丑陋的逻辑就只存在于一个地方。我不确定为什么您认为您的
map
解决方案成本高昂。如果您想根据名称动态调用构造函数,则必须使用动态语言而不是 Java。
Unfortunately there's no way around what you mentioned given the constraints.
If the popups are only slightly different they could be implemented as 1 class with a property that defines what type of popup you have.
Otherwise the best you can do it encapsulate it in a factory class like @JST mentioned, that way the ugly logic exists in just one place. I'm not sure why you consider your
map
solution costly though.If you want to dynamically invoke a constructor based on name, you're going to have to look at a dynamic language instead of Java.