2013-02-01 112 views
3

我有一个应用GRASP控制器模式的问题,同时保持它固体,更具体地说,同时保持它与一个责任。SOLID GRASP控制器模式?

Wikipedia's控制器模式定义说:

的控制器模式与分配系统事件处理,以代表整个系统或一种使用情形,非UI类的责任。 Controller对象是负责接收或处理系统事件的非用户界面对象。

而关于SOLID的single responsibility principle

在面向对象的编程,单一职责原则规定,每个类应该有一个责任,那责任应该完全由类封装。它的所有服务都应该与责任完全一致。

让我们来看一些示例代码。比方说,我有以下Java类:

public class foo { 
    public foo(){} 
    public int foo1(){/*Some code*/} 
    public String foo2(){/*Some code*/} 
    public String foo3(int foo31){/*Some code*/} 
} 

public class bar { 
    public bar(){} 
    public int bar1(){/*Some code*/} 
    public String bar2(){/*Some code*/} 
    public String bar3(int bar31){/*Some code*/} 
} 

什么是一个好的控制器实现,同时保持一个责任?我只是通过用例还是什么?例如:

public class bazController { 

    private foo fooInstance; 
    private bar barInstance; 

    public bazController(){ 
     this.fooInstance = new foo(); 
     this.barInstance = new bar(); 
    } 

    public void fooAction1(int arg){ 
     this.foo.foo3(arg); 
    } 

    public void barAction1(int arg){ 
     this.bar.bar3(arg); 
    } 

    public void fooAction2(){ 
     this.foo.foo1(); 
    } 

    public void barAction2(){ 
     this.bar.bar1(); 
    } 

} 

我是否守信的责任吗?我正在做这个,或者正确地理解这个吗?事先谢谢你。

编辑:如果bazController有这种方法会发生什么,使两个类相关?

public int bazAction(){ 
    return this.foo.fooAction1() + this.bar.barAction1(); 
} 

回答

2

我不是一个很多有经验的开发,但我会TR y基于对概念的理解,在此基础上探索我的想法。

单一责任关系:我相信,这是问题的答案:“你的班级对什么负责?当你要回答这个问题时,你应该只告诉一个责任。在你的情况下,答案是:“我的班级负责控制巴兹”(你的实施应该这样做)。

由于你的答案指定你实现它正确地只有一个责任。

但我觉得你的代码不符合SOLIDD。即依赖注入。你可以通过构造函数或通过其他方式注入了foobar

更新:仍然你的班级是罚款,因为你的班级的责任是control the baz

foobarbaz组件和你是通过你的bazCntroller控制他们的行动。

我可以说你违反了Single Responsibility当你添加一个做其他的工作比你的巴兹的控制方法。例如:

public void LogBazExecution() {} 
public int GetBazExecutionCount() {} 

正如你所看到的,它不是baz controller负责跟踪的巴兹动作多少次发射。

背后的原理的原因是ease of maintenance。当每个课程设计为只有一项责任时,您很容易在系统中找到失败的位置,并在需要时轻松扩展,而不会引入太多新错误。

+0

谢谢!如果两个班都相关,会发生什么?我刚刚编辑了我的帖子。为了简单起见,我也有意破坏这个原则。 –

+0

@ user1231958 - 更新了答案。 – NaveenBhat

+0

谢谢!事情现在更清晰了! –

1

这真的取决于类酒吧和企业如何紧密结合明智它们与控制器的业务背景后面的上下文。

在你的榜样,你必须与foo和与bar工作方法的工作方法,但方法是既foobar工作。对我而言,这表示foobar可能没有太多共同之处。

这是我会怎样改变你的例子:(假定foobar没有什么共同点):

public class fooController 
{ 
    private foo fooInstance; 

    public fooController() { 
     fooInstance = new foo 
    } 

    public void fooAction1(int arg){ 
     this.foo.foo3(arg); 
    } 

    public void fooAction2(){ 
     this.foo.foo1(); 
    } 
} 

public class barController 
{ 

    private bar barInstance; 

    public bazController(){ 
     this.barInstance = new bar(); 
    } 

    public void barAction1(int arg){ 
     this.bar.bar3(arg); 
    } 

    public void barAction2(){ 
     this.bar.bar1(); 
    } 
} 

编辑
,在那里你将有一个控制器,它代表一个例子不止一个业务逻辑实例可能是这个样子:

public class UserSettingsController 
{ 
    private UserAddressLogic addressLogic; 
    private UserPersonalInfoLogic personalInfoLogic; 

    public UserSettingsController() { 
     addressLogic = new UserAddressLogic(); 
     personalInfoLogic = new UserPersonalInfoLogic(); 
    } 

    public User GetUser() { 
     User user = new User(); 
     user.Address = addressLogic.GetUserAddress(); 
     user.PersonalInfo = personalInfoLogic.GetPersonalInfo(); 

     return user; 
    } 
} 
+0

谢谢!我刚编辑我的帖子,在这种情况下会发生什么? –

+1

编辑提供控制器如何委派给多个业务\数据对象的示例。在你的编辑中,如果foo和bar正在做相关的事情,你会在bazController中同时拥有foo和bar。 – jeuton

+0

谢谢你的例子! –