我有一个关于应用GRASP控制器模式的问题,同时保持它的SOLID,更具体地说,同时保持单一责任。
Wikipedia's控制器模式定义说:
Controller模式将处理系统事件的责任分配给表示整个系统或用例场景的非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();
}
答案 0 :(得分:2)
我不是一个经验丰富的开发人员,但我会尝试根据对这些概念的理解来探索我的想法。
单一责任:我相信,这是“你的班级负责什么?”这个问题的答案。当你要回答这个问题时,你应该只说一个责任。在你的情况下,答案是:“我的班级负责控制巴兹”(你的实施应该做到当然)。
由于您的答案仅指定了一项正确实施的责任。
但我认为您的代码不符合D
的{{1}}。即依赖注入。您可以通过构造函数或其他方式注入SOLID
和foo
。
更新:您的课程还可以,因为您的课程的责任是bar
。
control the baz
和foo
是bar
的组成部分,您可以通过baz
控制他们的操作。
我可以说当你添加的方法不是控制你的baz时,你违反了bazCntroller
。例如:
Single Responsibility
正如您所看到的,public void LogBazExecution() {}
public int GetBazExecutionCount() {}
不负责跟踪baz行动被解雇的次数。
原则背后的原因是baz controller
。当每个类只设计一个职责时,您可以轻松找到系统中故障的位置,并在需要时轻松扩展它,而不会引入太多新错误。
答案 1 :(得分:1)
这实际上取决于类 foo 和 bar 背后的背景,以及它们与控制器的业务环境有多紧密的商业关系。
< / p>
在您的示例中,您有适用于foo
的方法和使用bar
的方法,但 0 方法适用于foo
和{ {1}}。对我而言,这表明bar
和foo
可能没有多少共同之处。
这就是我改变你的例子的方式:(假设bar
和foo
没有任何共同点):
bar
修改强>
您将控制器委托给多个业务逻辑实例的示例可能如下所示:
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();
}
}