很抱歉这个标题令人困惑,我不知道我说的是不对,不知道这个叫什么东西......如果你想要的话,请在阅读问题后随意编辑。
当我注意到有很多地方可以使用策略模式时,我正在重构我的旧代码。我有一个库存系统和物品 - 有多种方法可以添加物品 - 正常方式,有力的方式等等。您还可以使用多种方式再次交换物品 - 所以我认为这些是很好的地方使用那种模式。
以下是添加项目的内容:
public interface IAddingStrategy<T> where T : AddArgs
{
bool Add(T args);
}
public class NormalAdd : IAddingStrategy<NormalAddArgs>
{
public bool Add(NormalAddArgs args)
{
// normal adding logic...
}
}
public class ForceAdd : IAddingStrategy<ForceAddArgs>
{
public bool Add(ForceAddArgs args)
{
// force adding logic...
}
}
// other strategies...
public abstract class AddArgs
{
}
public class NormalAddArgs : AddArgs
{
public readonly param1 p1;
public readonly param2 p2;
etc;
public NormalAddArgs(param1 p1, param2 p2, etc)
{
this.p1 = p1;
this.p2 = p2;
this.etc = etc;
}
}
public class ForceAddArgs : AddArgs
{
public param3 p3;
public ForceAddArgs(param3 p3)
{
this.p3 = p3;
}
}
// other adding args...
现在我正在尝试做什么 - 但不知道怎么做,是:
public class Adder
{
private Dictionary<Type, SOMETHING> dic = new Dictionary<Type, SOMETHING>();
public Adder()
{
dic.Add(typeof(NormalAdd), new NormalAdd());
dic.Add(typeof(ForceAdd), new ForceAdd());
dic.Add(typeof(EtcAdd), new EtcAdd());
}
}
SOMETHING
应该是什么?我希望它是任何添加策略 - 但如果我选择IAddingStrategy
- 它不起作用,因为它要求我指定<T>
参数,如果我这样做,字典不能保持所有可能的战略类型......;(
任何想法如何解决这个问题? SOMETHING
应该是什么?
在这种情况下,我是否正确使用策略模式?如果没有,最好的方法是什么?
感谢大家的帮助。
编辑:解决这个问题的方法是:
public interface IAddingStrategy
{
void Add(AddArgs args);
}
public class NormalAdd: IAddingStrategy
{
public void Add(AddArgs args)
{
if (args is NormalAddArgs)
// normal add logic
}
}
public class ForceAdd: IAddingStrategy
{
public void Add(AddArgs args)
{
if (args is ForceAddArgs)
// force add logic
}
}
然后字典只是<Type, IAddingStrategy>
但实际上,我不喜欢if
这个东西,它只是感觉不对 - 如果有人通过错误类型的arg会怎么样?这是在运行时才检测到的东西,我想在编译时检测到这个东西。 - 使用泛型我能够实现这一点。
答案 0 :(得分:1)
根据我的评论:最小化通用接口的暴露可能是有意义的,而不是要求调用者链的泛型参数。一种方法是实现通用和非通用接口。
优点:
缺点:
/// <summary>Some common base type.</summary>
public interface IAddArgs {}
/// <summary>Non-generic interface.</summary>
public interface IAddingStrategy
{
void Add( IAddArgs obj );
}
/// <summary>Generic version.</summary>
/// <typeparam name="T"></typeparam>
public interface IAddingStrategy<T> : IAddingStrategy
where T : IAddArgs
{
void Add( T obj );
}
public class NormalAddArgs : IAddArgs {}
public class NormalAdd : IAddingStrategy<NormalAddArgs>
{
public void Add( NormalAddArgs obj )
{
}
public void Add( IAddArgs obj )
{
Add( (NormalAddArgs)obj );
}
}
这确实留下了如何创建正确类型的参数的唠叨问题,即哪个类有足够的信息来创建NormalAddArgs
的实例,以便可以将其传递给适当的策略?
一种方法是让每种类型为您创建这些类型:
/// <summary>Non-generic interface.</summary>
public interface IAddingStrategy
{
void Add( IAddArgs obj );
// "context" can be a type that provides additional info
IAddArgs CreateAddArgs( object context );
}
public class NormalAdd : IAddingStrategy<NormalAddArgs>
{
public void Add( NormalAddArgs obj ) { }
public void Add( IAddArgs obj )
{
Add( (NormalAddArgs)obj );
}
public IAddArgs CreateAddArgs( object context )
{
return new NormalAddArgs();
}
}
答案 1 :(得分:0)
我不认为您的案例中会有Dictionary<Type, Interface<T>>
,因为您需要将T定义为词典中所有值的共同点。
Jon Skeet对类似的问题给出了很好的答案:Generic Dictionary with a value as a Interface with a Generic reference。我希望它对你也有所帮助。