首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >设计模式-策略模式

设计模式-策略模式
EN

Stack Overflow用户
提问于 2009-06-19 16:38:54
回答 4查看 2.3K关注 0票数 7

我是设计模式的初学者。

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

我正在尝试从策略模式中获得灵感。

因此,我将我的类和接口设计如下:

代码语言:javascript
复制
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
{
}

我应该做些什么来改进这个设计?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2009-06-19 16:45:52

首先,你所拥有的并不是一个策略模式的实例。Strategy Pattern允许对完成任务的方法进行动态规范。您在这里拥有的实际上更像是一个标准的接口设计,您可以通过接口继承来分配职责和能力。

编辑:让我们举个例子。假设您有一组Worker;您还有一组任务。每个工人都可以执行一项任务。这些任务可以由几个东西组成,比如DoFoo()和DoBar()。每个工人都不知道他们将执行什么任务;他们只知道当他们出现时,他们将执行任务。

因此,我们希望将Worker建模为具有他们将执行的任务。由于任务差异很大,我们将把Task实现为一个接口。

因此,我们将拥有:

代码语言:javascript
复制
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,第一个Worker有一个Task1任务,第二个Worker有一个Task2任务。为了使Worker执行其Task,我们调用Job类上的DoJob()方法,该方法只调用每个Worker上的DoWork()方法,该方法依次调用设置了Worker的每个Task上的DoTask()方法。

如果要将Worker更改为all do Task1,我们可以调用ChangeJobsToTask1()方法,该方法将Job包含的所有Worker对象的Task设置为Task1;如果此时对Job对象调用DoJob(),则所有<代码>D27都将执行<代码>D28任务。类似地,如果我们想要将Task更改为Task2,只需调用ChangeJobsToTask2()方法;然后,所有Worker都将在调用其DoWork()方法时执行Task2.DoTask()

这里重要的抽象点是Worker公开了一个DoWork()方法,但他们不一定知道正在做什么工作。也就是说,用于WorkerTasks是可互换的;Workers只知道他们要执行Task,但具体是什么对Workers并不重要。

票数 10
EN

Stack Overflow用户

发布于 2009-06-19 16:44:38

我在您的示例中看不到策略模式。策略模式在参数中接受“策略”类(通常继承自带有逻辑方法的接口,例如"DoJob()"),当调用一个方法时,它将通过应用先前传递的策略来执行操作,而不知道它将具体做什么。

在您的示例中,您可以有一个所有人员都继承的类,它有一个SetJob(IJobStrategy)和一个DoJob()方法,它将调用接口DoJob() (从IJobStrategy)。然后,您可以有多个继承IJobStrategy的具体作业。这样,您的人员不知道作业,您可以更改作业,而不必修改person类。

您可以查看示例和更多信息here

票数 2
EN

Stack Overflow用户

发布于 2009-06-19 16:53:04

这看起来更像是接口分离原则。现在,这在策略上确实发挥得很好,但这是我要做的不同之处。

Tester将不是一个具体的类,它将是一个TeamMember,并将TesterCompletesJobStrategy配置为它的CompletesJobStrategy。毕竟,阻止我测试的唯一原因是我目前在团队中分配的任务。

作为一个谈话要点,如果我的目标是一个战略,我会从更像这样的东西开始。

代码语言:javascript
复制
interface ICompleteJobStrategy {
   void CompleteJob(IResponsible responsibleParty);
}
class TesterCompletJobStrategy : ICompleteJobStrategy {
    ...
}
class TeamMember : IResponsible {
   TeamMember(ICompleteJobStrategy strat){ .. };
   void CompleteJob() { _completeJobStrategy.CompleteJob(this) ; }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1018913

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档