2014-06-21 6 views
0

이전 질문에서 아래 코드가 전략 패턴의 예라고 가르쳐 왔습니다. 특히 라인 _player.Draw(spriteBatch, _context);.이 전략 패턴을 올바르게 이해하고 있습니까?

나는 이전의 추가 메소드 호출과는 달리 그 라인과 그 라인 사이의 차이점을 보지 못했다.

내가 왜 _drawHugeContext에 대한 두 번째 호출을 사용하지 않고 누가 Player 클래스의 Draw()을 삭제했는지 설명 할 수 있습니까? 이 예가 너무 간단하고 전자가 훨씬 더 나은 상황이 있습니까?

public class Arena 
{ 
    Player _player; 
    IPlayerContext _drawHugeContext; 

    public void Draw(SpriteBatch spriteBatch) 
    { 
     _player.Draw(spriteBatch, _drawHugeContext); 
     _drawHugeContext.Draw(spriteBatch, _player); 
    } 
} 

public class Player 
{ 
    public int Percentage { get; private set; } 
    [...] //A few more fields 

    public void Draw(SpriteBatch spriteBatch, IPlayerContext context) 
    { 
     context.Draw(spriteBatch, this); 
    } 
} 

public class IPlayerContext 
{ 
    public void Draw(SpriteBatch spriteBatch, Player player) 
    { 
     spriteBatch.Draw(player.Percentage); 
     [...] //A few more fields drawn from player 
    } 
} 

답변

0

하지만, 아마도 당신은 아직 이해하지 않는 이유와 사용 방법에. 내가 당신에게 아주 간단한 예를 들어 보겠습니다.

의 당신이 세트를 가지고 있다고 가정 해 봅시다 개체를 정렬하고 싶습니다. 문제는 : 정렬 순서를 어떻게 지정합니까? .NET에서 이것은 일반적으로 passin에 의해 수행됩니다 이 객체들 중 두 개를 "Sort"메소드와 비교하는 방법을 알고있는 람다 또는 클래스.

var sorted = MyObjects.Sort((a,b) => a.Id > b.Id); 

이것은 당신의 논리를 분리 할 수 ​​있도록하는 방법을 특정 세트의 두 가지 요소를 주문하는 방법의 논리에 일반적으로 목록 정렬합니다.

당신의 경우에는 SpriteBatch이 호출에 삽입되는 전략이므로, 개체 구조가 정확하게 물건을 그리는 방법을 알 필요가 없습니다.

위의 예제를 사용하여 코드를 효과적으로 재구성 할 수 있다고 생각합니다.

0

나는 그 훌륭한 예를 생각하지 않습니다. 귀하의 질문에 대한 답변 :

1)이 예는 전략 선택 방법을 보여주지 않습니다. SpriteBatch는 이미 사전 결정되어 있습니다. 이렇게하면 예제가보다 완벽 해집니다.

2) 플레이어에서 직접 그리기를 호출하면 불필요한 간접 참조가 추가되어 어디에서/더 나은가를 즉시 알 수 없습니다.

많은 예제가 있지만 저는 Steven Metsker (GoF 패턴의 훌륭한 C# 책)의 "Design Patterns in C#"에서 사용한 전략 패턴의 예제를 포함 시켰습니다. 나는 위키 또는 doFactory 변형을 선호하지만 좋은 대안이기도합니다. 이것은 당신의 이해를 도울 것입니다.

고객의 위험 요인에 따라 견적 생성에 의존하는 보험 패키지가 있다고 가정 해 보겠습니다.

보험 패키지는이를 수행하는 데 견적 엔진을 사용합니다.

먼저 모든 전략에서 공유 할 전략 작업을 정의하는 메소드로 인터페이스를 정의하십시오.

public class OnlineQuoteEngineStrategy : IQuoteEngineStrategy 
{ 
    public decimal QuoteMeHappy(Customer c) { // online related retrieval } 
} 

public class OfflineQuoteEngineStrategy : IQuoteEngineStrategy 
{ 
    public decimal QuoteMeHappy(Customer c) { // offline related retrieval } 
} 

QuoteEngine 물건에 따라 선택된 전략을 디싱에 따라 결정

public interface IQuoteEngineStrategy 
{ 
    decimal QuoteMeHappy(int riskDetails) 
} 

그리고 주어진 2 예 구체적인 구현 :

인용 엔진 전략의 공개 얼굴 인터페이스에 의해 표현된다 고객. 여기서 나이는 결정적인 요소입니다.

public class QuoteEngine 
{ 

    public static IQuoteEngineStrategy GetQuotingEngine(Customer c) 
    { 
     if (c.Age < 25) 
     { 
      return new OnlineQuoteEngineStrategy(); 
     } 
     else 
     { 
      return new OfflineQuoteEngineStrategy(); 
     } 
    } 

}

마지막으로, InsurancePackage는 QuoteEngine이 전략을 선택하고 전략적 작업이 처음 확인 된 전화에 대한 몇 가지 정보를 전달하는 QuoteEngine를 사용합니다.

public class InsurancePackage 
{ 

    public decimal RiskQuote(Customer c) 
    { 
     return QuoteEngine.GetQuotingEngine(c).QuoteMeHappy(c); 
    } 
} 

전략 패턴은 소비자를 특정 전략의 구현 및 선택에서 숨 깁니다.

소비자로부터 전략적 결정을 내릴 수 있습니다. 이뿐 만 아니라 각각의 구체적인 전략은 서로 다른 외부 의존성에 대한 어댑터 역할을 할 수 있습니다.

또 다른 이점은 InsurancePackage를 변경하지 않고도 QuoteEngine이 단일 책임 원칙 (SRP)을 준수하고 InsurancePackage가 열린/닫힌 원칙 (수정을 위해 연장 된 연장을 위해 열려 있음)을 추가 할 수 있다는 것입니다. 마틴 너무 디자인의 SOLID 원칙은) 당신은 strategy patterns를 사용하는