2009-11-10 9 views
24

코드를 테스트 할 수있는 상태 (TDD 또는 다른 방식)로 유지하면서 관련 클래스의 커플 링을 최소화 할 수 있도록 클래스에 교차 횡단 문제를 주입하는 다양한 방법은 무엇입니까?교차 절단 문제를 주입하는 다른 방법은 무엇입니까?

예를 들어, 로깅 기능과 중앙 집중식 예외 관리가 모두 필요한 클래스가 있다고 가정 해보십시오. DIP를 사용해야하고 필요한 모든 문제를 인터페이스를 통해 필요한 클래스에 주입해야합니까? 교차 절단 기능이 필요한 각 클래스에 전달하는 서비스 위치 지정 도구를 사용해야합니까? 다른 해결책이 있습니까? 나는 틀린 질문을 완전히 요구하고 있는가?

답변

23

Decorator 디자인 패턴은 크로스 커팅 문제를 구현하기위한 훌륭한 출발점입니다.

먼저 해당 서비스를 모델링하는 인터페이스를 정의해야합니다. 그런 다음 교차 관심사를 전혀 고려하지 않고 해당 서비스의 실제 기능을 구현합니다.

그런 다음 다른 인스턴스를 둘러싼 장식 클래스를 구현하고 원하는 교차로 관련 문제를 구현할 수 있습니다.

이 방법은 POCO (Plain Old C# Objects)로 완전히 구현할 수 있으며 추가 프레임 워크가 필요하지 않습니다.

그러나 모든 추가 데코레이터를 작성하는 것에 지쳐 있으면 프레임 워크를 사용하는 것이 좋습니다. 명시 적 AOP 프레임 워크에 대한 경험이 없지만 Castle Windsor과 같은 대부분의 DI 컨테이너는 AOP와 유사한 기능을 제공합니다.


다음은 데코레이터 사용의 예입니다. 의는 다음과 같은 인터페이스를 가지고 있다고 가정 해 봅시다 :

귀하의 구체적인 구현은 콘솔에 문자열을 쓰는 매우 흥미있는 일, 할 수
public interface IMyInterface 
{ 
    void DoStuff(string s); 
} 

: 당신이 DoStuff 작업을 로그하려면

public class ConsoleThing : IMyInterface 
{ 
    public void DoStuff(string s) 
    { 
     Console.WriteLine(s); 
    } 
} 

을,

public class LoggingThing : IMyInterface 
{ 
    private readonly IMyInterface innerThing; 

    public LoggingThing(IMyInterface innerThing) 
    { 
     this.innerThing = innerThing; 
    } 

    public void DoStuff(string s) 
    { 
     this.innerThing.DoStuff(s); 
     Log.Write("DoStuff", s); 
    } 
} 
당신은 캐싱 데코레이터 정도의 보안을 구현 한, 그냥 WR처럼, 새로운 장식을 작성 유지할 수 있습니다

: 당신은 지금 로깅 데코레이터를 구현할 수 있습니다 그들을 서로 둘러싼 다.

참고 : 정적 인터페이스를 거의 사용하지 않으므로 Log.Write 인터페이스는 권장 사항이 아니며 단지 자리 표시자를 의미합니다. 실제 구현에서는 LoggingThing에 ILogger 인터페이스를 삽입했습니다.

+0

나는 장식 자도 고려했다.내 방법을 간결하게 유지하면 내가 제안한 예제 솔루션에서 기대할 수있는 컨트롤의 세분성을 희생하지 않을 것이라고 생각합니다. Decorator를 선호하는 이유가 있습니까? 데코 레이팅 된 클래스는 교차 절단 문제에 대한 지식이 없기 때문에? –

+0

문제를 처리 할 때 크로스 커팅 문제를 해결하는 가장 좋은 해결책입니까? –

+0

저는 실제 구현이 삐걱 거리는 것을 깨끗하게 유지하기 때문에 데코레이터를 전략 주입보다 선호합니다. 나는 종종 그것을 선호하지만 때로는 예를 들어 인터넷에 의해 제공되는 차단을 사용할 수도 있습니다. 캐슬 윈저. –

4

Observer 패턴을 사용할 수 있습니다.

주제에는 관찰자 모음이 있습니다. 주제가 조치를 수행하면 관찰자에게 변경 사항을 알립니다. 그러면 관찰자는 주제가없는 행동을 수행 할 수 있습니다. 내가 그렇게 구문 오류를 용서하십시오, 자바 사용 해요

public interface IThingObserver 
{ 
    void Notify(); // can also pass in a parameter with event information 
} 

public class Thing 
{ 
    private readonly ICollection<IThingObserver> observers; 

    public Thing() 
    { 
     observers = new List<IThingObserver>(); 
    } 

    public void RegisterObserver(IThingObserver observer) 
    { 
     observers.Add(observer); 
    } 

    public void UnregisterObserver(IThingObserver observer) 
    { 
     observers.Remove(observer); 
    } 

    private void NotifyObservers() 
    { 
     foreach (IThingObserver observer in observers) 
     { 
      observer.Notify(); 
     } 
    } 

    public void DoIt() 
    { 
     Console.WriteLine("Doing it..."); 
     NotifyObservers(); 
    } 
} 

public class LoggingThingObserver : IThingObserver 
{ 
    public void Notify() 
    { 
     Log.Write("It is done."); 
    } 
} 

:

다음은 예입니다.

+0

나는 원래 '09 년에 이것을 만들었지 만 답변에 감사한다. 옵서버는 OCP와의 관심사와 히트를 분리하는 데 실제로 도움이되는 좋은 추천입니다. –

관련 문제