I'm playing around with design patterns, and at the moment I'm working with the prototype pattern. The pattern made me wonder, why do I need an interface for this pattern, can't I achieve the same functionality without an interface?

I have created two examples, can anyone explain me why I need the interface?

Interface example:

This is my interface class:

interface IWeapon
{
    IWeapon Clone();
}

My concrete class:

class Rifle : IWeapon
{

    public IWeapon Clone()
    {
        return (IWeapon)this.MemberwiseClone();
    }

}

The Cloning process

 //Create rifle
 Rifle rifle = new Rifle();
 rifle.Name = "M4A1";
 rifle.Rounds = 30;

 //Copy Rifle
 Rifle rifleCopy = (Rifle)rifle.Clone();

This is how I clone without an interface

public Rifle Clone()
{
   return (Rifle)this.MemberwiseClone();
}

Can someone explain me the advantages of using the implementation with the interface over the one without an interface?

有帮助吗?

解决方案

Interfaces are great when you have classes that do the same thing, but use different methods to achieve it.

Using your example, lets say we have something like this...

public interface ILongRangeWeapon
{
    void Fire();
}

Now, lets say you have these classes...

public class Rifle : ILongRangeWeapon
{
    public void Fire()
    {
        // Pull the trigger
    }
}

public class NuclearMissile : ILongRangeWeapon
{
    public void Fire()
    {
        // Press the red button
    }
}

Now you can use ILongRangeWeapon in your code, and it doesn't matter which mechanism it uses to fire, it just knows that it CAN fire.

A more practical application would be connecting to the internet. There are multiple ways to connect, modem, lan, wifi, etc. However, you just don't even care HOW the instance connects, you just want it to connect.

There are some purists that say you should make everything an interface. I think it adds complexity where it isn't needed just for the sake of adding complexity. It's up to you as a developer to decide if you should use an interface or not.

其他提示

The interface in the prototype pattern is supposed to look more like this:

interface ICloneable
{
    ICloneable Clone();
}

I.e. you don't use the interface to mark your class as a weapon, you use it to mark that it has a Clone method that can be used to create a copy.

Suppose you had a method:

public void CloneAndShoot(IWeapon weapon) {
    IWeapon cloned = weapon.clone();
    cloned.shoot();
}

Now, if your interface would be defines as follows:

interface IWeapon {
    IWeapon clone();
    void shoot();
}

Your method could accept all kinds of weapons without caring:

CloneAndShoot(new M16());
CloneAndShoot(new M4A4());

Possible to avoid subclasses of an object creator in the client application, like the abstract factory pattern does.

https://en.wikipedia.org/wiki/Prototype_pattern

The point of an interface is to define a common and enforceable structure for a class.

The advantages are not evident in your example because you declared just one type of IWeapon. The real advantage comes in when you start creating different weapons.

The IWeapon class is there to define the things you expect from every weapon, that way every weapon class you create that inherits from IWeapon is forced to follow that.

Ultimately, it's predictable in terms of what you expect it to have in terms of methods. The things those methods do, however, is unique to each weapon.

An example:

interface IWeapon
{
    IWeapon Clone();
    Boolean HasAmmo();
    Int32 RoundInMagazine();
    Double GetCaliber();
    Fire();
    //etc.
}

//1st weapon
public class Shotgun : IWeapon
{
    private Int32 _ammo = 5;

    public void Clone()
    {
        return (IWeapon)this.MemberwiseClone();
    }

    public Boolean HasAmmo()
    {
        return _ammo > 0;
    }

    public Int32 RoundsInMagazine()
    {
        return _ammo;
    }

    public Double GetCaliber()
    {
        return 12.0;
    }

    public void Fire()
    {
        MessageBox.Show("bang!");
    }
}

//1st weapon
public class Rifle : IWeapon
{
    private Int32 _ammo = 30;

    public void Clone()
    {
        return (IWeapon)this.MemberwiseClone();
    }

    public Boolean HasAmmo()
    {
        return _ammo > 0;
    }

    public Int32 RoundsInMagazine()
    {
        return _ammo;
    }

    public Double GetCaliber()
    {
        return 5.56;
    }

    public void Fire()
    {
        MessageBox.Show("bang! bang! bang!");
    }
}

With that in place, I can define any number of weapons, and each will provide me with that minimum class content. The real advantage is that each one implements these methods in their own unique ways.

Think of an interface like a template for a set of related classes.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top