2012-08-23 2 views
3

두 개의 결합 클래스 DhcpServerSessionManager이 있습니다. 그 커플 링을 이끌어 내 사양에서 다음과 같은 요구 사항을 가지고 :스펙이 주장 할 때 클래스 결합을 피하는 방법

  • DhcpServerSessionManager
  • SessionManager 세션을 시작해야합니다 (세션을 만드는 동안 예를 들어 오류가 발생) 것을 금지하는 경우 IP 주소 임대를 발행하지 않아야합니다 DhcpServer에 의해 새로운 임대의 생성시 그 임대가 만료 또는 SessionManager가 해당 세션을 중지하는 경우 임대를 파괴해야 반면 DhcpServer에 클라이언트
  • 에 의해 명시 적으로 해제됩니다 즉시 세션을 파괴
  • (시스템 관리자의 요청에 의해 예)

처음에는 모든 코드를 단일 클래스에 넣으려고합니다. 그러나 책임은 별개 있었다, 그래서 나는 두 가지로 분할하고 두 개의 인터페이스 생성 :

class ISessionObserver(object): 
    def onSessionStart(**kwargs): pass 
    def onSessionStop(**kwargs): pass 

class IDhcpObserver(object): 
    def onBeforeLeaseCreate(**kwargs): 
     """ 
     return False to cancel lease creation 
     """ 
     pass 
    def onLeaseCreate(**kwargs): pass 
    def onLeaseDestroy(**kwargs): pass 

가 그럼 난 DhcpServerSessionManagerISessionObserverIDhcpObserver을 구현합니다. 그리고 그게 커플 링으로 이어졌습니다. 클래스가 서로 직접 의존하지는 않지만 서로의 패키지에 선언 된 인터페이스에 의존합니다.

나중에 세션 시작을 위해 SessionManager의 논리를 그대로 유지하면서 다른 프로토콜을 추가하고 싶습니다. 나는 이것을 IAnotherProtocolObserver으로 구현하고 싶지 않다.

또한 DHCP 서버는 내 세션 개념과 아무 관련이 없습니다. Twisted (내가 사용하고있는)에 DHCP 프로토콜 구현이 없기 때문에, SessionManager이나 패키지에는 의존성이없는 별도의 프로젝트로 배포하려고했습니다.

코드 조각을 느슨하게 결합하여 유지하면서 사양 요구 사항을 어떻게 충족시킬 수 있습니까?

답변

5

클래스를 분리하는 좋은 방법은 events을 사용하는 것입니다.

그래서해야 할 일은 무언가가 일어날 때 이벤트를 "시작"하는 것입니다. 예 : SessionManager이 세션을 만들 수있을 때 "세션 생성됨"이벤트를 보냅니다. DhcpServer이 해당 이벤트를 수신 대기하고 수신 할 때리스를 준비하십시오.

이제 나머지 두 개를 만들고 이벤트 리스너를 구성하는 세 번째 클래스 만 있으면됩니다.

이 솔루션의 장점은 모든 것을 간단하게 유지합니다. 단위 테스트를 작성할 때 올바른 이벤트가 발생했는지 확인하는 것만으로 클래스 중 하나만 필요합니다.

+0

정확히 내가 한 일입니다. 내 옵저버 인터페이스는 같은 목적으로 사용됩니다. 그러나 이것으로 문제가 해결되지는 않습니다 :'DhcpServer'는'SessionManager'가 발생시키는 이벤트 유형을 알아야하고 그 반대도 마찬가지입니다. 그것이 수정 된 동일한 커플 링입니다. –

+0

내가 말했듯이 : 이벤트를 연결하는 클래스 사이에 클래스가 필요합니다. "세션 생성"이벤트를 취한 다음 DHCP 서버에서 메소드를 호출하고 그 반대의 경우도 마찬가지입니다. 이 클래스는 다른 클래스보다 상위 레벨에 있기 때문에 연결을 수행 할 수 있습니다. 이것은 서비스 클래스를 깨끗하게 유지합니다. –

+2

그래, 내가 너를 정확하게 이해한다면, 내 관찰자 인터페이스는 괜찮아. 하지만'DhcpServer'와'SessionManager'에서 교차 구현하는 대신 세 번째를 소개해야합니다.이 클래스는 옵서버 인터페이스를 구현하고'DhcpServer'와'SessionManager' 둘 다의 메소드를 호출하는 중재자가 될 것입니다, 맞습니까? –