2013-02-01 1 views
3

GRASP 컨트롤러 패턴을 솔리드로 유지하면서 더 구체적으로 단일 책임으로 유지하면서 GRASP 컨트롤러 패턴을 적용하는 것에 대한 질문이 있습니다.SOLID GRASP 컨트롤러 패턴?

Wikipedia's 컨트롤러 패턴 정의는 말한다 :

컨트롤러 패턴이 전체 시스템 또는 유스 케이스 시나리오를 나타내는 비 UI 클래스에 시스템 이벤트를 처리하는 책임을 할당합니다. Controller 객체는 시스템 이벤트를 수신하거나 처리하는 비 사용자 인터페이스 객체입니다.

고체의 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

저는 많은 경험이있는 개발자가 아니지만, 이 개념에 대한 이해를 바탕으로 내 아이디어를 탐색 해보십시오.

단일 책임 : 나는 "당신의 수업은 무엇을 책임지고 있습니까?"라는 질문에 대한 대답이라고 믿습니다. 이 질문에 대답 할 때, 오직 한 가지 책임 만 말해야합니다. 귀하의 경우 대답은 : "내 수업은 baz를 통제 할 책임이 있습니다"(귀하의 구현은 과정을 수강해야합니다).

답변에 단 하나의 책임 만 명시되어 있으므로 올바르게 구현했습니다.

하지만 코드가 D (SOLID)을 충족시키지 못한다고 생각합니다. 즉 의존성 주입. 생성자 또는 다른 방법을 통해 foobar을 주입 할 수 있습니다.

업데이트 : 클래스의 책임은 control the baz입니다. 그래도 클래스는 괜찮습니다.

foobarbaz의 구성 요소이고, 당신이 당신의 bazCntroller를 통해 자신의 행동을 제어한다.

귀하의 baz를 제어하는 ​​것과 다른 작업을 수행하는 방법을 추가 할 때 Single Responsibility을 위반했다고 말할 수 있습니다. 예는 :

당신이 볼 수 있듯이
public void LogBazExecution() {} 
public int GetBazExecutionCount() {} 

, 바즈 액션 해고 얼마나 많은 시간을 추적 할 수있는 baz controller의 책임이 아니다.

원칙의 이유는 ease of maintenance입니다. 각 클래스가 오직 하나의 책임을 지도록 설계되면 시스템에서 오류의 위치를 ​​쉽게 찾을 수 있으며 필요한 경우 버그를 많이 도입하지 않고도 쉽게 확장 할 수 있습니다.

+0

감사합니다. 두 수업 모두 관련성이 있다면 어떻게 될까요? 방금 내 글을 편집했습니다. 또한 나는 단순성을 위해 의도적으로 그 원칙을 깨뜨리고있다. –

+0

@ user1231958 - 대답을 업데이트했습니다. – NaveenBhat

+0

감사합니다. 상황은 지금 더 명확합니다! –

1

은 정말 클래스 foo는와 얼마나 가깝게 정렬 사업 지혜가 컨트롤러의 비즈니스 컨텍스트에있는 뒤의 상황에 따라 달라집니다. 당신의 예에서

, 당신은 foobar 작업 방법과 작업 방법,하지만 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

예를 들어 주셔서 감사합니다! –