我的代码中有这个
switch (auctionType)
{
case AuctionTypes.OpenBid:
destination = new EnglishAuction();
break;
case AuctionTypes.FixedPrice:
destination = new BuyoutAuction();
break;
case AuctionTypes.ClosedBid:
destination = new SealedFirstPriceAuction();
break;
default:
destination = new Auction();
break;
}
我想知道的是如何使用策略或状态模式消除switch语句?
答案 0 :(得分:3)
您发布的代码确实是工厂。在工厂里,开关都可以。
您返回的Auction
个对象可能属于策略。战略和国家之间的区别是微妙的,但很重要:
在策略中,您使用不同的算法来完成本质上相同的事情。调用者不必知道这一点,这是一个实现细节。战略的一些例子可能是
HybridDictionary
中,操作可以在简单的ListDictionary
中实现,而集合很小,并且在集合增长时使用Hashtable
。这有时会导致混乱,因为不同怪物的行为是“明显的”或至少对最终用户可见,而后者则不然。另一方面, 可见,因为它希望更快/更精确。通常情况下,这并不是那么明显。
在状态模式中,另一方面,类的行为会有所不同。经典状态模式示例是TcpSocket
类:套接字可以是连接或断开状态。这对客户端是可见的,并且在断开连接的套接字上调用Disconnect()
是一个错误,就像在已连接的套接字上调用Connect()
一样。对象本身可以改变其状态,并且它是可见的并且是外部已知的。
由于您使用的是工厂,因此返回的Auction
对象在其生命周期内可能不会更改类型,这是正常操作的一部分。国家的实施通常不通过工厂,因为它们不可互换。相反,您可以在内部使用TcpSocket
创建TcpSocketClosed
,并在成功调用TcpSocketConnected
后更改为Connect()
。
答案 1 :(得分:1)
只是为了好玩,并且参考@Raphaël关于在Java中消除switch语句的方法的评论,你可以在C#中获得类似的结果(虽然有更多的工作),如下所示:
创建一个包含Type
的属性,并使用其无参数构造函数创建它的实例:
public class TypeAttribute : Attribute
{
private readonly Type _type;
public TypeAttribute(Type type)
{
_type = type;
}
public T CreateInstance()
{
return (T)Activator.CreateInstance(_type);
}
}
...用属性
装饰你的enum
public enum AuctionTypes
{
[Type(typeof(EnglishAuction))]
OpenBid,
[Type(typeof(BuyoutAuction))]
FixedPrice,
[Type(typeof(SealedFirstPriceAuction))]
ClosedBid,
[Type(typeof(Auction))]
Default
}
...添加扩展方法:
public static class Extensions
{
public static Auction CreateAuction(this AuctionTypes auctionType)
{
return typeof(AuctionTypes)
.GetMember(auctionType.ToString())
.First()
.GetCustomAttributes(typeof(TypeAttribute), inherit: false)
.Cast<TypeAttribute>()
.First()
.CreateInstance<Auction>();
}
}
...你可以这样打电话:
var auction = auctionType.CreateAuction();
这是来自内存的,如果我们有通用属性会更好,但你去了。