设计模式 - 接口隔离

时间:2009-06-30 14:49:24

标签: design-patterns

假设我开发了一个摔跤游戏,所有摔跤手都互相争斗。

所以我设计了类和接口,如下所示:

public interface IWrestler
{
    void Attack();
}

public class Sumo : IWrestler
{
    public Sumo()
    {
    }

    public void Attack()
    {
        Console.Write("Sumo attacked the opponent...");
    }
}

public class Shaolin : IWrestler
{
     //------ etc.
}

今年我希望摔跤运动员携带武器(之前没想过)。

假设我已经创建了大量的类。

现在可以使用什么设计模式来解决这个问题?或者,我现在该如何解决这个问题?

最初可以使用哪种设计模式来避免这个问题?

4 个答案:

答案 0 :(得分:4)

我相信,我不会深入研究这个问题的设计模式。关于手头的设计问题,我会自发地说,携带武器的摔跤手不是摔跤手,而是一个应该用新界面代表的战士。为了向后兼容,我们可以要求所有战士也是摔跤手:

public interface IWrestler
{
    void Attack();
}    
public interface IWarrior : IWrestler
{
    void WeaponedAttack();
}
// let's assume that Sumo's don't carry weapons
public class Sumo : IWrestler
{
    public void Attack()
    {
        Console.Write("Sumo attacked the opponent...");
    }
}
//..but Shaolin do:
public class Shaolin : IWarrior
{
    public void Attack()
    {
        Console.Write("Shaolin attacked the opponent as a wrestler...");
    }

    public void WeaponedAttack()
    {
        Console.Write("Shaolin attacked the opponent as a warrior...");
    }
}

关于if Sumo是否带有棍子的评论:我想用棍子Sumo也可以认为是战士;所以让它实现IWarrior,并使用WeaponedAttack进行攻击。除非棒专门用于防御(但这似乎不是接口的一部分;我无法看到攻击者将如何“看到”对手,反之亦然)。

也许你应该有另一种规模的接口:IAttackerIDefender,你有IAttacker.Attack(IDefender)IDefender.BeingAttacked(IAttacker)并且每个类都实现了这两个接口?这样可以确定某种评分机制决定谁赢得这场战斗。 (只是抛出想法..)

答案 1 :(得分:2)

  

现在可以使用什么设计模式   解决这个问题?或者,我该怎么办?   现在解决这个问题?

对于已经设计的类,除了可以帮助您解决此问题的AOP之外,没有可以用静态语言神奇地应用的设计模式。你必须为每个摔跤手添加另一个界面IWeapon和一个武器列表的引用。

  

可以使用哪种设计模式   最初是为了避免这个问题吗?

不要这样打扰自己。你在设计课程方面做得很好。重要的是要认识到变化的模式,并在你的设计中支持它。否则,考虑所有可能的情况只是浪费时间。

答案 2 :(得分:0)

我要问的问题是你是否真的想要开始使用Sumo类,或者是IWrestler接口。

似乎IWrestler必须对大量事情负责 - 解决攻击,确定一些内部统计数据等。这违反了单一责任原则。

我还打赌,当你完成时,IWrestler将拥有大量的方法,其中一些方法几乎与彼此无关。这是另一个迹象,表明你正在进入泥浆大球的反模式。

攻击和防守可能是相互关联的事实表明,可能还有另一个类(或更多!)隐藏在那里,并负责在两者之间进行仲裁。

作为最终建议,可能值得考虑这不是基于数据结构的观点,而是从与用户的交互点。对从用户输入到最终结果的数据流建模可能会提出一些可能的设计,这些设计乍一看并不明显。从这个观点来看,很多经典设计模式真正开始闪耀。

答案 3 :(得分:-1)

  

最初可以使用哪种设计模式来避免这个问题?

看看Visitor。它允许您在不修改这些结构的情况下向现有对象结构添加新操作