7

我是设计模式的初学者。

假设我正在开发一个 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
{
}

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

4

4 回答 4

10

好吧,首先,您所拥有的不是策略模式的实例。策略模式允许动态规范完成工作的方法。你在这里所拥有的实际上更像是一个标准的接口设计,你通过接口继承来分配职责和能力。

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

因此,我们希望将 Workers 建模为他们将执行的任务。由于任务变化很大,我们将任务实现为接口。

所以我们会有:

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();
      }
   }
}

所以发生的事情是,当我们实例化 a 时JobJob创建了两个Workers。第一个WorkerTask1任务;第二个WorkerTask2任务。为了让Workers 做它们Task的 s,我们调用类DoJob()上的方法,它只调用每个s 上的方法,然后又调用每个设置s 的s 上的方法。 JobDoWork()WorkerDoTask()TaskWorker

如果我们想将Workers 更改为 all do Task1,我们调用该ChangeJobsToTask1()方法,该方法将 ; 包含的所有对象设置Task为; 如果此时我们在对象上调用 ,所有的s 都会执行任务。同样,如果我们想将s 更改为,只需调用方法即可;然后,所有的s 将在调用他们的方法时执行。Task1WorkerJobDoJob()JobWorkerTask1TaskTask2ChangeJobsToTask2()WorkerTask2.DoTask()DoWork()

这里抽象的重点是Workers 暴露了一个DoWork()方法,但它们不一定知道正在完成的工作是什么。也就是说,Tasks 的Workers 是可以互换的;Workers 只知道他们会做 a ,但具体内容对sTask来说并不重要Worker

于 2009-06-19T16:45:52.020 回答
2

我在您的示例中没有看到策略模式。策略模式在参​​数中采用“策略”类(通常从具有逻辑方法的接口继承,例如“DoJob()”),当调用方法时,它将通过应用较早传递的策略来执行操作,而不知道它是什么具体会做。

在您的示例中,您可以拥有一个您的所有人都继承的类,该类具有 SetJob(IJobStrategy) 和 DoJob() 方法,该方法将调用接口 DoJob()(来自 IJobStrategy)。比,你可以有多个继承 IJobStrategy 的具体工作。这样,您的员工不知道工作,您可以更改工作而无需修改人员类。

您可以在此处查看示例和更多信息。

于 2009-06-19T16:44:37.777 回答
0

这看起来更像是接口隔离原则。现在,这确实与策略相得益彰,但这就是我要做出的不同之处。

Tester 不会是一个具体的类,它将是一个 TeamMember,其 TesterCompletesJobStrategy 配置为 CompletesJobStrategy。毕竟,唯一让我无法进行测试的是我目前在团队中分配的任务。

只是作为一个话题,如果我的目标是策略,我会从更像这样的东西开始。

interface ICompleteJobStrategy {
   void CompleteJob(IResponsible responsibleParty);
}
class TesterCompletJobStrategy : ICompleteJobStrategy {
    ...
}
class TeamMember : IResponsible {
   TeamMember(ICompleteJobStrategy strat){ .. };
   void CompleteJob() { _completeJobStrategy.CompleteJob(this) ; }
}
于 2009-06-19T16:53:04.027 回答
0

你可以在 C# 中使用“动态”,而不是像这样:

方法(动态输入)

方法(DTO1 输入) 方法(DTO2 输入) 方法(DTO3 输入)

没有遵守时间错误

于 2020-08-07T14:40:03.173 回答