user366312
user366312

Reputation: 17026

Design Pattern - Interface Segregation

Suppose I developed a wrestling game where all wrestlers fight with each-other.

So I designed the classes and interfaces like the following:

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.
}

This year I want the wrestlers to carry weapons (which was not thought earlier).

Suppose I have already created a large number of classes.

What design pattern can be used now to solve this problem? Or, How should I solve this problem now?

What design pattern could be used initially to avoid this problem?

Upvotes: 0

Views: 529

Answers (4)

kyoryu
kyoryu

Reputation: 13065

The question I'd ask is whether or not you really want a Sumo class to begin with, or an IWrestler interface.

It seems like a IWrestler will have to be responsible for a ton of things - resolving attacks, determining some internal statistics, etc. This kind of violates the Single Responsibility Principle.

I'd also bet that by the time you're done, IWrestler will have a large number of methods, some of which will have almost nothing to do with each other. That's another sign that you're drifting into the Big Ball of Mud anti-pattern.

The fact that attacking and defending will probably be interrelated suggests that there may be another class (or more!) hiding there with the responsibility of arbitrating between the two.

As a final suggestion, it may be worthwhile to consider this not from a data-structure-based standpoint, but from the point of interaction with the user. Modeling the flow of data from the user input to the eventual result may suggest some possible designs that aren't apparent at first glance. It's when looking at things from this view that a lot of the classic design patterns really start to shine.

Upvotes: 0

Ralph
Ralph

Reputation: 5232

What design pattern could be used initially to avoid this problem?

Have a look at Visitor. It allows you to add new operations to existing object structures without modifying those structures

Upvotes: -1

Fredrik Mörk
Fredrik Mörk

Reputation: 158409

I would not dive too deeply into design patterns for this issue, I believe. On the design problem at hand, I would spontaneously say that a wrestler that is carrying a weapon is not a wrestler, but a warrior, which should be represented by a new interface. For backwards compatibility, we can require all warriors to also be wrestlers:

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...");
    }
}

Regarding the comment with if Sumo is armed with a stick: I guess that Sumo with a stick may also be considered a warrior; so have it implement IWarrior instead, and attack with the stick using WeaponedAttack. Unless the stick is exclusively for defense (but that does not seem to be part of the interfaces yet; I can't see how the attacker will "see" the opponent or vice versa).

Perhaps you should have the interfaces on another scale: IAttacker and IDefender, where you have IAttacker.Attack(IDefender) and IDefender.BeingAttacked(IAttacker) and have each class implement both? That way there can problably be some sort of scoring mechanism deciding who wins the battle. (just tossing ideas..)

Upvotes: 4

Boris Pavlović
Boris Pavlović

Reputation: 64650

What design pattern can be used now to solve this problem? Or, How should I solve this problem now?

For the already designed classes there's no design pattern that can be magically applied in a static language except AOP that can help you solving this problem. You will have to add another interface IWeapon and a reference to a list of weapons to every wrestler.

What design pattern could be used initially to avoid this problem?

Don't bother yourself this way. You had done a good job designing your classes. It's important to recognize a pattern of change and to support it in your desing. Otherwise it would be just a waste of time to think of all possible cases.

Upvotes: 2

Related Questions