2009-06-19 121 views
6

我是Design Patterns的初学者。设计模式 - 策略模式

假设我正在开发一个C#应用程序来跟踪由开发团队(即项目跟踪器)中的各个成员执行的开发工作。

我试图从策略模式中获得灵感。

所以我设计我的类和接口如下:

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(拼写错误,我认为) – 2009-06-19 16:40:58

回答

8

那么,首先,你有什么没有一个战略模式的实例。 Strategy Pattern允许动态指定完成任务的方法。你在这里得到的是更多的标准接口设计,你可以通过接口继承来分配责任和能力。

编辑:让我们用一个例子。假设你有一群工人;你也有一套任务。每名工人都可以执行任务。这些任务可以包含几个方面,比如DoFoo()和DoBar()。每个工人不知道他们将执行什么任务;他们只是知道他们什么时候出现,他们会做一个任务。

因此,我们希望将工人模型化为他们将执行的任务。由于任务差别很大,因此我们将实施该任务作为界面。

因此,我们将有:

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,则Job创建两个Worker秒。第一个WorkerTask1任务;第二个Worker有一个Task2任务。为了使Worker就做他们的Task S,我们呼吁Job类,它只是呼吁每个Worker s,这反过来调用DoTask()方法在每个Task S的的DoWork()方法DoJob()方法的Worker小号被设置。

如果我们想改变Worker s到所有做Task1,我们称之为ChangeJobsToTask1()方法,设定TaskTask1全部由Job包含的Worker对象;如果在这一点上,我们将DoJob()称为Job对象,则所有的Worker都将执行Task1任务。同样,如果我们想将Task s更改为Task2,只需调用ChangeJobsToTask2()方法;所有Worker将在调用DoWork()方法时执行Task2.DoTask()

这里抽象的重要一点是Worker揭示了一个DoWork()方法,但他们不一定知道正在做什么工作。也就是说,WorkerTask可以互换; Worker只是知道他们要做Task,但它的具体细节对Worker并不重要。

+0

从本书深入浅出设计模式,我发现“的原则确定的是改变你的应用程序的各方面和他们有什么保持不变分开”。 你能建议我该怎么做到这一点? – 2009-06-19 16:51:52

+1

@JMSA:我不能建议如何做到这一点,而不知道你的应用程序的所有信息,但我会添加信息来解释一个例子。 – 2009-06-19 17:09:01

2

我没有看到你的例子中的策略模式。策略模式采用参数中的“策略”类(通常从具有逻辑方法的接口继承,例如“DoJob()”),并且在调用某个方法时,它将通过应用先前传递的策略执行操作,而不知道它是什么会精确地做。

在你的例子中,你可以有一个类,你所有的人都继承了一个SetJob(IJobStrategy)并且有一个DoJob()方法来调用接口DoJob()(来自IJobStrategy)。比你可以有多个继承IJobStrategy的具体工作。这样,你的人不知道这个工作,你可以改变工作,而无需修改人员课程。

你可以看到例子和更多信息here

0

这看起来更像界面分离原则。现在,这在战略上表现得很好,但这是我做出的不同之处。

测试人员不会是一个具体类,它将成为一个TeamMember,配置TesterCompletesJobStrategy作为CompletesJobStrategy。毕竟,阻止我进行测试的唯一因素是我目前在团队中分配的任务。

就像谈话一样,如果我是针对策略的话,我会从更像这样的事情开始。

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