我希望将策略模式用于.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)
{
}
}
答案 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 ");
}
}