用于处理不同类型对象之间交互的设计模式

时间:2017-03-09 05:26:25

标签: java c# oop design-patterns software-design

我有一个C#程序,它有一个名为Ball的类,它有两个enum字段BallColorBallType。有7种球颜色(红色,蓝色,黄色等)和7种球类型(网球,足球,保龄球等)。球对象可以具有颜色和类型的任何可能组合。

在我的程序中,我有许多不同颜色和类型组合的Ball个对象。球可以通过碰撞相互作用。当两个球碰撞时,它会触发由名为handleInteraction(ball1, ball2)的函数处理的交互。两个球之间的相互作用取决于每个球的类型和颜色。例如,如果任何保龄球击中任何乒乓球,则乒乓球被破坏并且保龄球继续以其原始速度移动。但是,如果任何足球与保龄球相撞,则足球会从保龄球上弹开,保龄球的速度会降低n。另一个例子,如果红色网球与绿色乒乓球发生碰撞,乒乓球会从网球上反弹,乒乓球的颜色会变成网球的颜色(红色)。

在我的handleInteraction(ball1, ball2)函数中,我一直使用嵌套的switch语句处理交互。但是,当我编写更多代码来处理所有场景时,嵌套的switch语句似乎不是正确的方法。

有人能想出更好的方法来处理球之间的互动吗?

3 个答案:

答案 0 :(得分:2)

一种解决方案是为交互结果和球创建界面:

public interface IInteractionResult
{
    void Handle();
}

public interface IBall
{
    BallTypeEnum BallType { get; }

    IInteractionResult HandleInteraction(IBall ball);
}

并实现实现IInteractionResult的每个可能的类,其中Handle方法提供交互逻辑:

public class DestroyInteractionResult : IInteractionResult
{

    public void Handle()
    {
        //your code for destroy result behaviour
    }
}

public class BounceInteractionResult : IInteractionResult
{

    public void Handle()
    {
        //your code for bounce result behaviour
    }
}

public class NothingInteractionResult : IInteractionResult
{

    public void Handle()
    {
        //your code for nothing
    }
}

在此之后实施Ball的课程,该课程将在IBall的实施时使用switch语句实施HandleInteraction。例如SoccerBall

public class SoccerBall : IBall
{
    public BallTypeEnum BallType
    {
        get { return BallTypeEnum.Soccer; }
    }

    public IInteractionResult HandleInteraction(IBall ball)
    {
        switch (ball.BallType)
        {
            case BallTypeEnum.Soccer:
                return new BounceInteractionResult();
            case BallTypeEnum.Bowl:
                return new DestroyInteractionResult();
            case BallTypeEnum.PingPong:
                return new BounceInteractionResult();
            // and so on
        }

        throw new NotImplementedException("Undefined ball type");
    }
}

每种球类型和每次交互的单独类可帮助您将每种类型的单个逻辑收集到单个类中。

handleInteraction看起来像是:

public void handleInteraction(IBall ball1, IBall ball2)
{
    var interaction = ball1.HandleInteraction(ball2);

    interaction.Handle();
}

在我看来,这是最灵活的解决方案。某种战略模式。

答案 1 :(得分:1)

更好的方法是在Ball Class中获得更多属性,如下所示。更像是实际物理

prop double Mass { get; set;)

内部handleInteraction

If(b1.Mass / b2.Mass < 0.1) // Make your Own ratios
    //Destrioy Ball
else if(..)
    //Move in derecton or Bounce

我的方法是,为所有行为制作属性

答案 2 :(得分:0)

考虑抽象碰撞的概念。有关于速度,颜色等的规则。将这些规则放在表格中,然后进行查找并应用它们。

  

例如,如果任何保龄球击中任何乒乓球,则乒乓球被破坏,保龄球继续以其原始速度移动。

碰撞后球可以被摧毁(或不被摧毁)。 (布尔值)

  

然而,如果任何足球与保龄球碰撞,则足球会从保龄球中弹回,保龄球的速度会降低n。

球的速度减少了n。

球可以改变方向(“跳出”)。

  

另一个例子,如果红色网球与绿色乒乓球发生碰撞,则乒乓球从网球上反弹,乒乓球的颜色变为与网球相同的颜色(红色)。

球可以改变颜色。

在这些示例中,规则有4个维度。如果您非常确定该模型,您可以轻松编写代码来定义每次碰撞的规则(在表格或地图中)并在没有很多条件的情况下应用规则。