采用其他接口的策略模式方法

时间:2013-12-12 00:06:31

标签: c# generics design-patterns interface

我希望将策略模式用于.net应用程序。我正在简化代码,但想法是一样的。有一个运输接口,将有2个具体的类,Car& amp;摩托车,唯一要求是实施可驾驶方法。为了实现它,我想使用策略模式和IDriveableStrategy接口,它将采用一个实现ITransport的类并使用该类中的信息来确定ITransport是否可驱动。我看到一些帖子质疑向战略发送背景的做法,但我现在想忽略那场辩论。如果我实现一个名为MotorcycleDriveableStrategy的类,我想将其用作Motorcycle类的策略。

在下面的代码中,您会注意到我有两个特定于Motorcycle类的附加属性,我想用它来评估ITransport是否可行。在MotorcycleDriveableStrategy中,我已经评论了我是如何理想地实现这个类的,(有了驱动器实现接口的isDriveable,因为Motorcycle实现了ITransport)但是当我尝试时我得到了编译错误,所以我必须保持方法期望ITransport接口。

我可以通过使IDriveableStrategy接口采用实现ITransport的通用来实现我想要的耦合

IDriveableStrategy<T> where T : ITransport

并声明

MotorcycleDriveableStrategy<Motorcycle>

但我想知道我是否错过了更大的画面。如何在仿制药之前实现这一目标?策略模式是否应始终根据公开的接口实现来评估上下文?策略接口是否应该将接口作为参数?是否有另一种方法可以实现这一目标,而无需将numWheels添加到ITransport接口或使IDriveableStrategy成为通用的?提前感谢您的任何建议或见解。

public interface ITransport
  {
        boolean driveable();
  }

public class Car : ITransport
{
     private driveableStrategy {get;set;}
     public boolean driveable()
     {
         return driveableStrategy.isDriveable();
     }

}

public class Motorcycle: ITransport
{
     private driveableStrategy {get;set;}
     private int numWheels {get;set;}
     private string weatherExceptions {get;set;}
     public Motorcycle(IDriveableStrategy driveableStrategy,int numWheels,string weatherExceptions)
     {
         this.driveableStrategy = driveableStrategy;
         this.numWheels = numWheels;
         this.weatherExceptions = weatherExceptions;
     }

     public boolean driveable()
     {
         return driveableStrategy.isDriveable();
     }

}

public interface IDriveableStrategy
{
        boolean isDriveable(ITransport transport);
}

public class MotorcycleDriveableStrategy
{
        //What i would like to do
        /*public boolean isDriveable(Motorcycle transport)
           {
               return transport.numWheels > 2;
           }
         */
        public boolean isDriveable(ITransport transport)
        {

        }
}

1 个答案:

答案 0 :(得分:1)

首先我要说的是,将上下文发送到策略是没有问题的,IMO个人策略的是抽象出细节,这样你就可以随心所欲地插入另一个。 IStrategy接口方法允许用户类为所有策略执行相同的命令,但我不会将策略本身限制为接口方法。个人战略应该对背景有深入的了解。 如果我完全错过了你的观点,请告诉我,如果有人有不同的意见,我也会非常感兴趣。

在你的例子中,MotorcycleDriveableStrategy是我们应该决定摩托车驾驶性能的唯一地方。因此:

public class MotorcycleDriveableStrategy : IDriveableStrategy
{
    //What i would like to do
    public bool IsDriveable(ITransport transport)
    {
        var mc = transport as Motorcycle;
        if (mc == null) return false;
        return mc.NumWheels > 2;
    }
}

如果你对整件事感兴趣:

public interface ITransport { bool Driveable();}
public interface IDriveableStrategy { bool IsDriveable(ITransport transport);}

public class Car : ITransport
{
    private IDriveableStrategy Strategy { get; set; }
    public bool Driveable()
    {
        return Strategy.IsDriveable(this);
    }
}

public class Motorcycle : ITransport
{
    private IDriveableStrategy Strategy { get; set; }
    public int NumWheels { get; set; }
    public string WeatherExceptions { get; set; }

    public Motorcycle(IDriveableStrategy driveableStrategy, int numWheels, string weatherExceptions)
    {
        Strategy = driveableStrategy;
        NumWheels = numWheels;
        WeatherExceptions = weatherExceptions;
    }

    public bool Driveable()
    {
        return Strategy.IsDriveable(this);
    }
}

public class MotorcycleDriveableStrategy : IDriveableStrategy
{
    //What i would like to do
    public bool IsDriveable(ITransport transport)
    {
        var mc = transport as Motorcycle;
        if (mc == null) return false;
        return mc.NumWheels > 2;
    }
}

// And for the Car strategy
public class CarDriveableStrategy : IDriveableStrategy
{
    //place ur implementation here ...
    public bool IsDriveable(ITransport transport) {return true;}
}

public class TestMotorcycle
{
    public TestMotorcycle()
    {
        var mcs = new MotorcycleDriveableStrategy();
        var mc = new Motorcycle(mcs, 2, "abc");
        Console.WriteLine("Motorcycle is {0}drivable", mc.Driveable()?"":"not ");
    }
}