2009-06-19 12 views
6

저는 Design Patterns의 초보자입니다.디자인 패턴 - 전략 패턴

개발 팀 (즉, 프로젝트 트래커)의 다양한 구성원이 수행 한 개발 작업을 추적하기 위해 C# 응용 프로그램을 개발하고 있다고 가정합니다.

저는 Strategy Pattern에서 영감을 얻으려고합니다. 다음과 같이

그래서 나는 나의 클래스와 인터페이스를 설계하고있다 :

나는이 디자인을 개선하기 위해 무엇을해야 일
interface IEmployee 
{ 
    void Retires(); 
    void TakesLeave(); 
} 

interface IResponsible 
{ 
void AcknowledgeJobAccomplish(); 
void CompletesJob(); 
} 

interface ILeader 
{ 
    void FormsTeam(); 
    void RecruitsNewMember(); 
    void KicksOutMemberFromTheTeam(); 
    void AssignsJob(); 
void UnassignsJob(); 
void QueriesTheJobStatus(); 
void ChangesTheJobStatus(); 
} 

interface IPersistent 
{ 
    void Save(); 
    void Update(); 
    void Delete(); 
} 

abstract class TeamMember : IEmployee, IResponsible, IPersistent 
{ 
    string Name; 
} 

class Programmer : TeamMember 
{ 
} 

class LeadProgrammer : Programmer, ILeader 
{ 
    ProgrammerCollection associateProgrammers; 
} 

class ProjectManager : TeamMember, ILeader 
{ 
    TeamMemberCollection teamMembers; 
} 

abstract class Tester : TeamMember 
{ 
} 

class UnitTester : Tester 
{ 
} 

class QC : Tester 
{ 
} 

class SupportStaff : TeamMember 
{ 
} 

?

+0

TeamMamber : TeamMember 책 헤드 퍼스트 디자인 패턴에서 –

답변

8

먼저, 전략 패턴의 인스턴스가 없습니다. Strategy Pattern은 일을 끝내기위한 방법의 동적 인 사양을 허용합니다. 여기에있는 것은 인터페이스 상속을 통해 책임과 기능을 할당하는 표준 인터페이스 디자인입니다.

편집 : 예를 들어 보겠습니다. 근로자 그룹이 있다고 가정 해 보겠습니다. 당신은 또한 일련의 작업들을 가지고 있습니다. 각 작업자는 작업을 수행 할 수 있습니다. 이러한 작업은 DoFoo() 및 DoBar()와 같은 여러 작업으로 구성 될 수 있습니다. 각 작업자는 수행 할 작업을 알지 못합니다. 그들은 단지 그들이 할 일을 보여줄 때를 압니다.

그래서 우리는 작업자가 수행 할 작업이 있다고 생각하고 싶습니다. Tasks가 매우 다양하기 때문에 우리는 Task를 하나의 인터페이스로 구현할 것입니다.

그래서 우리가해야합니다 :
public class Worker 
{ 
    public Task myTask; 

    public Worker(Task task) 
    { 
     myTask = task; 
    } 

    public void DoWork() 
     { 
     myTask.DoTask(); 
     } 
    } 
} 

Interface Task 
{ 
    void DoTask(); 
} 

public class Task1 : Task 
{ 
    public void DoTask() 
    { 
    // Do whatever Task1 will do 
    } 
} 

public class Task2 : Task 
{ 
    public void DoTask() 
    { 
    // Do whatever Task2 will do 
    } 
} 

public class Job 
{ 
    public List<Worker> workers; 

    public void Job() 
    { 
     workers.Add(new Worker(new Task1())); 
     workers.Add(new Worker(new Task2())); 
    } 

    public void DoJob() 
    { 
     foreach (Worker worker in workers) 
     { 
     worker.DoWork(); 
     } 
    } 

    public void ChangeJobsToTask1() 
    { 
     foreach (Worker worker in workers) 
     { 
     worker.myTask = new Task1(); 
     } 
    } 

    public void ChangeJobsToTask2() 
    { 
     foreach (Worker worker in workers) 
     { 
     worker.myTask = new Task2(); 
     } 
    } 
} 

그래서 무슨 일 것은 우리가 Job를 인스턴스화 할 때 JobWorker의를 생성한다는 것이다. 첫 번째 Worker에는 Task1 작업이 있습니다. 두 번째 Worker에는 Task2 작업이 있습니다. Worker s는 우리가 차례로 Task의 각각에 DoTask() 메서드를 호출하는 Worker의, 각각의 DoWork() 메서드를 호출하는 Job 클래스에 DoJob() 메소드를 호출, 자신의 Task의를 할 수 있도록하려면 그 Worker의 함께 설정되었습니다.우리 모두가 할 Task1Worker의를 변경하려면

, 우리는 Job에 포함 된 Worker 모든 개체에 대한 Task1Task를 설정 ChangeJobsToTask1() 메소드를 호출; 이 시점에서 Job 개체의 DoJob()을 호출하면 Worker 모두가 Task1 작업을 수행합니다. 마찬가지로 TaskTask2으로 변경하려면 ChangeJobsToTask2() 메서드를 호출하면됩니다. 모든 WorkerDoWork() 메서드가 호출 될 때 Task2.DoTask()을 실행합니다.

여기에서 추상화의 중요한 점은 DoWork() 메서드가 노출되어 있지만 실제로 수행되는 작업이 무엇인지 알 수 없다는 것입니다. 즉, Worker에 대한 Task은 서로 바꿔 사용할 수 있습니다. WorkerTask을 수행 할 것임을 알고 있지만, 구체적인 내용은 Worker에 중요하지 않습니다.

+0

(내가 생각하는 오류 철자) 나는 원칙 "다양 응용 프로그램의 측면을 확인하고 동일하게 유지 것과 구분"을 발견했다. 어떻게해야합니까? –

+1

@ JMSA : 귀하의 신청서에 대해 모른 채 어떻게해야하는지에 대해서는 제안 할 수 없지만 예를 설명하기 위해 답변에 정보를 추가하겠습니다. –

+0

이 모든 논의에서 실제로 본 것은 내 사례가 전략 패턴을 구현하는 데 완벽하지 않다는 것을 발견했습니다. 아닌가요? –

2

예제에 전략 패턴이 표시되지 않습니다. 전략 패턴은 매개 변수에서 "전략"클래스 (일반적으로 로직 메소드 인 인터페이스 "DoJob()"를 상속받습니다. 메소드가 호출되면 이전에 전달 된 전략을 적용하지 않고 그것을 적용하여 작업을 수행합니다 구체적으로 할 것입니다.

예를 들어, 모든 사람들이 SetJob (IJobStrategy)을 상속 받고 DoJob() 인터페이스 (IJobStrategy에서)를 호출하는 DoJob() 메소드를 가질 수있는 클래스가있을 수 있습니다. 당신은 IJobStrategy를 계승 한 여러 가지 구체적인 직업을 가질 수 있습니다. 이 방법으로, 사람들은 직업을 알지 못하며 사람 클래스를 수정하지 않고도 직업을 바꿀 수 있습니다.

예제 및 자세한 내용은 here을 참조하십시오.

0

이것은 인터페이스 분리 원리와 훨씬 비슷합니다. 이제 전략으로는 훌륭하게 작동합니다. 그러나 여기에 제가 다른 점이 있습니다.

테스터는 Concrete 클래스가 아니며 CompletesJobStrategy로 구성된 TesterCompletesJobStrategy가있는 TeamMember가됩니다. 결국 테스트에서 나를 지켜주는 유일한 방법은 팀에서 현재 할당 된 작업입니다.

내가 전략을 목표로 삼을 경우 이야기 지점과 마찬가지로, 더 좋아하는 것으로 시작할 것입니다.

interface ICompleteJobStrategy { 
    void CompleteJob(IResponsible responsibleParty); 
} 
class TesterCompletJobStrategy : ICompleteJobStrategy { 
    ... 
} 
class TeamMember : IResponsible { 
    TeamMember(ICompleteJobStrategy strat){ .. }; 
    void CompleteJob() { _completeJobStrategy.CompleteJob(this) ; } 
} 
+0

인터페이스에 'public'이 필요하지 않습니다. –