2012-04-22 113 views
2

Im头部设计模式的读者,我注意到了这一点。这个例子违反了好莱坞的原则“不要打电话给我们,我们给你打电话”

“好莱坞原则,不要打电话给我们,我们给你打电话”

这意味着高层次的组件告诉低层组件“不要打电话给我们,我们给你打电话”

高级组件是一个与其他低级组件定义的BEHAVIOR类。

我的问题是......这个例子违反了不要打电话给我们,我们称之为原则吗?这也来自使用状态模式的书。

public class GumballMachine 
{ 
    //other state instance here 

    State NoQuarterState; 
    State HasQuarterState; 

    public GumballMachine(int numberGumballs) 
    { 
     NoQuarterState = new NoQuarterState(this); 
     HasQuarterState = new HasQuarterState(this);  

     //other state objects here assigning to state instance  
    } 

    public void insertQuarter() 
    { 
     state.insertQuarter(); 
    } 

    void setState(State state) 
    { 
     this.state = state; 
    } 

    public State getHasQuarterState() 
    { 
     return hasQuarterState; 
    } 

    //more code here 
} 

=========================================== =========================

public interface State 
{ 
    //abstract methods 
} 

================== ==================================================

public class NoQuarterState implements State 
{ 
    GumballMachine gumballMachine; 

    public NoQuarterState(GumballMachine gumballMachine) 
    { 
     this.gumballMachine = gumballMachine; 
    } 

    public void insertQuarter() 
    { 
     System.out.println("You inserted a quarter"); 
     gumballMachine.setState(gumballMachine.getHasQuarterState()); // change the state to HasQuarterState 
    } 
} 

因为在此示例GumballMachine需要NoQuarterStateinsertQuarterBehavior()为自己insertQuarterBehavior所以这意味着GumballMachine类是高级别部分并NoquarterState类是低级别的组件。但看看NoQuarterState类,类也取决于gumballMachine的的setState()getHasQuarterState()为它的insertQuarter()行为

他们互相依赖。 C-I-R-C-U-L-A-R -D-E-P-E-N-D-E-N-C-I-E-S

+0

是的,我完全同意这是S-H-I-T-T-Y D-E-S-I-G-N这种情况经常发生在作者试图解释其观点仅在大型项目中显而易见的概念时,但在这样一个简单的例子中。这是过度工程和分工几乎杂乱无章。有一件事让我感到奇怪:如果这是来自一本书,它怎么不尊重无处不在的java命名约定?实例字段必须遵循lowerCamelCase约定。 – 2012-04-22 11:35:43

+0

@MarkoTopolnik我想它是由原始海报手动重新输入。这里是该书的原始版本:http://comet.lehman.cuny.edu/cocchi/CMP346/state/GumballMachine.java – bezmax 2012-04-22 11:55:59

+0

我明白了。那么,在那个代码中,设计错误还没有被提交。这就是你提到的海报的全部内容。 'State'对象应该返回**新的状态,而不是直接将它设置在父对象上。这就是设计误入歧途的地方。它是可以修复的。 – 2012-04-22 12:01:27

回答

1

首先,你应该阅读关于State Pattern
你发布的是一个相当简单的版本。在您发布的代码,唯一的一次new被称为是在Gumball机,因为状态关联/属于Gumball机将实例化了中央和唯一的地方,这实际上是不坏。它也是唯一添加/删除它们的地方。所以具体类的实例化在代码中是一个地方。

NoQuarterStateassociatedGumball机(以及任何其他State这件事),这使培训就业处,因为只有NoQuarterState知道这将是它的处理后跟进,有效地使Gumball成箱移动的下一个正确的状态取决于每个州的结果。这样Gumball可以改变State而不知道一个状态如何或在什么条件下跟随另一个状态。这被封装在State具体实例中。

而事实上Gumball只知道States在其代码中的各种getterssetters。它所调用的唯一方法是那些属于State而不是NoQuarterState等。
所以尽管这是一个相当简化的例子,可以改进(顺便说一句,不要以为它允许复制粘贴一个例子出来书),它并没有违反你本身所要求的原则,Holywood原则的核心思想是关于宽松的合作关系,这个代码并没有违反它恕我直言

+0

当然这个例子确实违反了松散耦合的原理!有时候作者为了简单而牺牲完美。 – 2012-04-22 13:24:07

+0

@AdriaanKoster:现在最重要的是你的系统有多松散,有人必须调用'new'。这个实例是多么受控制,在一个集中的位置是什么导致了差异。我承认你正在尝试的是什么但尽管简单化了他的例子,但我认为作者可以阐明他的观点 – Cratylus 2012-04-22 14:42:23

1

你应该看到GumballMachine作为国家运作的上下文。这种模式要求各国能够提及任何其他国家并改变现状。这意味着紧密耦合是在这里实现的,它允许GumballMachine不依赖于状态级逻辑,而是负责状态的生命周期及其共同的参考点。

原则和模式不是设计工作的最终目标。最后,你必须为手头的问题提出一个合适的解决方案,有时候某些模式和原则不适用。话虽如此,如果你注意到你真的违反了一个重要原则(如松散耦合/紧密凝聚),这是一个迹象表明某种东西可能是错的,你至少应该问自己为什么是这种情况,如果可以避免在你的问题的限制之内。

0

是的,它确实违反了好莱坞原则,正是你指出的原因。但正如同一本书强调的那样,这些原则不是法律,并且经常被侵犯。例如,回调是好莱坞原则的常见和有用的违反。

相关问题