0

我的代码中有这个

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 语句?

4

2 回答 2

3

您发布的代码确实是工厂。在工厂里,开关没问题。

您返回的Auction对象可能属于策略。策略和状态之间的区别很微妙,但很重要:

  • 策略中,您使用不同的算法来完成基本相同的事情。调用者不必知道这一点,这是一个实现细节。一些策略示例可能是

    • 在电脑游戏中,您希望您的 AI 坏人攻击玩家。不同的敌人可能会使用不同的策略,因为他们可能会飞越障碍物、传送到玩家身边或具有不同的战斗风格。
    • 在 aHybridDictionary中,操作可能在ListDictionary集合较小时以简单的方式实现,并Hashtable在集合增长时使用 a。
    • 在 CAD 应用程序中,您可能已经实施了不同的策略来计算复杂方程的解,具体取决于各种因素,以找到速度与精度的最佳水平。

    这有时会导致混淆,因为不同怪物的行为是“显而易见的”或至少对最终用户可见,而后者不是。另一方面,它可见的,因为它希望更快/更精确。通常情况下,它并不那么明显。

  • 另一方面,在状态模式中,类的行为会有所不同。经典的状态模式示例是一个TcpSocket类:套接字可能处于连接或断开状态等。这对客户端是可见的,并且调用Disconnect()断开连接的套接字是错误的,就像调用Connect()已经连接的套接字一样。对象本身可以改变它的状态,并且它是可见的并且为外界所知。

由于您使用的是工厂,因此Auction作为正常操作的一部分,返回的对象在其生命周期内可能不会更改类型。状态的实现通常不经过工厂,因为它们不可互换。相反,您将创建一个TcpSocketwhich 在内部使用并在您成功调用后TcpSocketClosed更改为.TcpSocketConnectedConnect()

于 2013-06-26T17:19:21.677 回答
1

只是为了好玩,并参考@Raphaël 关于在 Java 中消除 switch 语句的方法的评论,您可以在 C# 中得到类似的结果(尽管需要更多的工作),如下所示:

创建一个包含 a 的属性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();

这是从记忆中得出的,如果我们有通用属性会更好,但是你去吧。

于 2013-06-27T05:51:12.997 回答