假设您具有可见性属性的控件A,B,C,D和E.您还有状态1,2,3,4,5和6,其中将显示控件的各种组合。
目前,这是由每个州的switch语句处理的:即
Select Case PageState
case "1"
a.visible = false
b.visible = true
c.visible = false
d.visible = true
e.visible = false
case "2"
a.visible = true
b.visible = true
c.visible = false
d.visible = true
e.visible = false
case ...
End Select
你可以想象,这会变得很痛苦,因为每个州都需要为每个控件提供show / hide语句。我怎样才能重构这一点,以便添加控件和/或状态变得微不足道?
我的第一直觉是扩展控件并添加它应该显示的状态集合,但这听起来有点过分。
修改 如果这有其他影响,我在我的问题中故意模糊。在我目前的实例中,所讨论的“控件”是ASP面板。这有什么改变吗?
答案 0 :(得分:3)
答案 1 :(得分:2)
使用状态模式。让每个州在您的页面上运行(抽象为界面):
public interface IControlSituationPage // your page implements this
{
void SetAvisibility(bool visibility);
void SetBVisibility(bool visibility);
...
}
...
public interface PageState // each state implements this
{
void ApplyState(IControlSituationPage page);
}
..然后,在确定您所处的状态(可能是工厂模式)之后,请调用方法:
// ... somewhere..
_state.ApplyState(this);
当然,这取代了实际使用更强大的演示模式,如MVC或MVP。
答案 2 :(得分:1)
[注意:我是一个java人,所以下面的实现是用Java编写的 - 它应该与C#或你想要使用的其他语言非常相似]
Rob指出上述解决方案存在的问题 - 它实际上无法维护。
它也非常冗长(GoF状态模式通常是......)。
有时状态模式并不是你应该使用的。
你如何解决问题并让数据驱动它?
将其视为“应该显示哪些州?”
尝试以下内容:
粗略的实现(未编译/测试)
public enum MyStates {State1, State2, State3...}
public class VisibilityManager {
private Map<Component, Set<MyStates>> managedComponents =
new HashMap<Component, Set<MyStates>>();
private Component component;
public void setVisibility(Component component, MyStates... states) {
Set<MyStates> visibleStates = EnumSet.of(states);
managedComponents.put(component, states);
}
public void update(MyStates currentState) {
for (Map.Entry<Component, Set<MyStates>> e : managedComponents.entrySet())
e.getKey().setVisible(e.getValue().contains(currentState));
}
}
// then in your GUI setup
VisibilityManager v = new VisibilityManager();
v.setVisibility(comp1, MyStates.State1, MyStates.State2);
v.setVisibility(comp1, MyStates.State3);
v.setVisibility(comp1, MyStates.State1, MyStates.State3, MyStates.State5);
...
// and when you change the state
v.update(newState);
希望这有帮助!
答案 3 :(得分:0)