设计模式-策略模式

发布于 2024-07-25 04:50:48 字数 1055 浏览 5 评论 0原文

我是设计模式的初学者。

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

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

I am a beginner in Design Patterns.

Suppose I am developing a C# application to track the development works performed by various members in development team (i.e. a Project Tracker).

I am trying to be inspired by Strategy Pattern.

So I am designing my classes and interfaces as follows:

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
{
}

What things should I do to improve this design?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

旧竹 2024-08-01 04:50:48

好吧,首先,您所拥有的不是策略模式的实例。 策略模式允许动态指定完成任务的方法。 这里实际上更多的是标准接口设计,通过接口继承来分配职责和能力。

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

因此,我们希望将 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();
      }
   }
}

那么,当我们实例化一个 Job 时,该 Job 创建两个 Worker 。 第一个 Worker 有一个 Task1 任务; 第二个 Worker 有一个 Task2 任务。 为了让 Worker 执行其任务,我们调用 Job 类的 DoJob() 方法,它只调用每个 Worker 上的 DoWork() 方法,而 Worker 又调用每个 Worker 上的 DoTask() 方法设置Worker的code>Task。

如果我们想要将 Worker 更改为所有执行 Task1 的操作,我们调用 ChangeJobsToTask1() 方法,该方法设置 Task<对于Job 包含的所有Worker 对象,/code> 到Task1; 如果此时我们对 Job 对象调用 DoJob(),则所有 Worker 都将执行 Task1< /代码> 任务。 同样,如果我们想将Task更改为Task2,只需调用ChangeJobsToTask2()方法即可; 当调用其 DoWork() 方法时,所有 Worker 都将执行 Task2.DoTask()

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

Well, first off, what you have there is not an instance of a Strategy pattern. The Strategy Pattern allows for the dynamic specification of a method for getting things done. What you have here is really more of a standard interface design, where you allocate responsibilities and abilities by interface inheritance.

Edit: Let's use an example. Let's say that you have a group of Workers; you also have a set of Tasks. Each Worker can perform a Task. These Tasks can consist if several things, such as DoFoo() and DoBar(). Each Worker does not know what Task they will perform; they just know when they show up that they will do a Task.

So we'll want to model Workers as having a Task that they will perform. Since the Tasks vary widely, we'll implement the Task as an interface.

So we'll have:

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

So what happens is that when we instantiate a Job, the Job creates two Workers. The first Worker has a Task1 task; the second Worker has a Task2 task. To make the Workers do their Tasks, we call the DoJob() method on the Job class, which just calls the DoWork() method on each of the Workers, which in turn calls the DoTask() method on each of the Tasks that the Workers were set with.

If we want to change the Workers to all do Task1, we call the ChangeJobsToTask1() method, which sets the Task to Task1 for all of the Worker objects contained by the Job; if, at that point, we call the DoJob() on the Job object, all the Workers will perform the Task1 task. Similarly, if we want to change the Tasks to Task2, just call the ChangeJobsToTask2() method; all the Workers will then execute the Task2.DoTask() when their DoWork() method is called.

The important point of abstraction here is that the Workers expose a DoWork() method, but they do not necessarily know what work it is that is being done. That is, the Tasks for the Workers are interchangeable; the Workers just know that they're going to do a Task, but the specifics of what it is are unimportant to the Workers.

音盲 2024-08-01 04:50:48

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

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

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

I do not see the strategy pattern in your example. Strategy pattern take the "strategy" class (usually inherit from an Interface with a logic method, example "DoJob()") in parameter and when a method is called, it will do operation on by applying the strategy passing earlier without knowing what it will concretly do.

In your example you could have a class that all your people inherit that have a SetJob(IJobStrategy) and have a DoJob() method that will call the interface DoJob() (from IJobStrategy). Than, you can have multiple concrete job that inherit IJobStrategy. This way, your people do not know the job and you can change the job without having to modify the person class.

You can see example and more information here.

舂唻埖巳落 2024-08-01 04:50:48

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

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

作为一个谈话要点,如果我的目标是一个策略,我会从类似这样的事情开始。

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

This seems much more like the Interface Segregation Principle. Now, that does play well with strategy, but here's what I'd make different.

Tester wouldn't be a Concrete class, it would be a TeamMember with a TesterCompletesJobStrategy configured as it's CompletesJobStrategy. After all, the only thing keeping me from testing is my currently assigned task on the team.

Just as a talking point, I'd start with something more like this if I was targeting a Strategy.

interface ICompleteJobStrategy {
   void CompleteJob(IResponsible responsibleParty);
}
class TesterCompletJobStrategy : ICompleteJobStrategy {
    ...
}
class TeamMember : IResponsible {
   TeamMember(ICompleteJobStrategy strat){ .. };
   void CompleteJob() { _completeJobStrategy.CompleteJob(this) ; }
}
裂开嘴轻声笑有多痛 2024-08-01 04:50:48

你可以在c#中使用“dynamic”来代替
像这样:

方法(动态输入)

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

无编译时间错误的

u can use "dynamic" in c# instead
like this:

Method(dynamic input)

Method(DTO1 input)
Method(DTO2 input)
Method(DTO3 input)

without complie time error

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文