我是设计模式的初学者。
假设我正在开发一个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
{
}我应该做些什么来改进这个设计?
发布于 2009-06-19 16:45:52
首先,你所拥有的并不是一个策略模式的实例。Strategy Pattern允许对完成任务的方法进行动态规范。您在这里拥有的实际上更像是一个标准的接口设计,您可以通过接口继承来分配职责和能力。
编辑:让我们举个例子。假设您有一组Worker;您还有一组任务。每个工人都可以执行一项任务。这些任务可以由几个东西组成,比如DoFoo()和DoBar()。每个工人都不知道他们将执行什么任务;他们只知道当他们出现时,他们将执行任务。
因此,我们希望将Worker建模为具有他们将执行的任务。由于任务差异很大,我们将把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时,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()方法,但他们不一定知道正在做什么工作。也就是说,用于Worker的Tasks是可互换的;Workers只知道他们要执行Task,但具体是什么对Workers并不重要。
发布于 2009-06-19 16:44:38
我在您的示例中看不到策略模式。策略模式在参数中接受“策略”类(通常继承自带有逻辑方法的接口,例如"DoJob()"),当调用一个方法时,它将通过应用先前传递的策略来执行操作,而不知道它将具体做什么。
在您的示例中,您可以有一个所有人员都继承的类,它有一个SetJob(IJobStrategy)和一个DoJob()方法,它将调用接口DoJob() (从IJobStrategy)。然后,您可以有多个继承IJobStrategy的具体作业。这样,您的人员不知道作业,您可以更改作业,而不必修改person类。
您可以查看示例和更多信息here。
发布于 2009-06-19 16:53:04
这看起来更像是接口分离原则。现在,这在策略上确实发挥得很好,但这是我要做的不同之处。
Tester将不是一个具体的类,它将是一个TeamMember,并将TesterCompletesJobStrategy配置为它的CompletesJobStrategy。毕竟,阻止我测试的唯一原因是我目前在团队中分配的任务。
作为一个谈话要点,如果我的目标是一个战略,我会从更像这样的东西开始。
interface ICompleteJobStrategy {
void CompleteJob(IResponsible responsibleParty);
}
class TesterCompletJobStrategy : ICompleteJobStrategy {
...
}
class TeamMember : IResponsible {
TeamMember(ICompleteJobStrategy strat){ .. };
void CompleteJob() { _completeJobStrategy.CompleteJob(this) ; }
}https://stackoverflow.com/questions/1018913
复制相似问题