2014-01-23 2 views
3

Я играю с шаблонами дизайна, и на данный момент я работаю с шаблоном прототипа. Модель заставила меня задаться вопросом, зачем мне нужен интерфейс для этого шаблона, не могу ли я достичь такой же функциональности без интерфейса?Prototype Pattern, зачем мне нужен интерфейс?

Я создал два примера, может ли кто-нибудь объяснить мне, зачем мне нужен интерфейс? Пример

Интерфейс:

Это мой интерфейс класса:

interface IWeapon 
{ 
    IWeapon Clone(); 
} 

Мой конкретный класс:

class Rifle : IWeapon 
{ 

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

} 

Процесс клонирования

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

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

Это, как я клонировать withou t a интерфейс

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

Может ли кто-нибудь объяснить мне преимущества использования реализации с интерфейсом над интерфейсом без интерфейса?

ответ

2

Интерфейсы великолепны, когда у вас есть классы, которые выполняют одно и то же, но используют разные методы для его достижения.

Используя ваш пример, позволяет сказать, что у нас есть что-то вроде этого ...

public interface ILongRangeWeapon 
{ 
    void Fire(); 
} 

Теперь, позволяет сказать, что у вас есть эти классы ...

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

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

Теперь вы можете использовать ILongRangeWeapon в вашем код, и не имеет значения, какой механизм он использует для стрельбы, он просто знает, что он может стрелять.

Более практичное приложение будет подключаться к Интернету. Существует несколько способов подключения, модем, lan, wifi и т. Д. Однако вам просто неинтересно, КАК подключается экземпляр, вы просто хотите, чтобы он подключался.

Есть некоторые пуристы, которые говорят, что вы должны сделать все интерфейсом. Я думаю, что это добавляет сложности, когда это не нужно просто для того, чтобы добавить сложность. Это зависит от вас, как разработчика, чтобы решить, следует ли использовать интерфейс или нет.

+0

У вас есть точка сложности. Я создал свои интерфейсы очень мало, но когда они мне нужны, они были неоценимы. – DonBoitnott

+0

Создание интерфейсов для всего требует определенного типа дизайна. Если что-то хорошо компоненты, то создание интерфейсов компонентов позволяет очень адаптируемую, проверяемую кодовую базу. Но это нужно делать хорошо. Даже тогда вам все равно может не понадобиться * все *, чтобы иметь интерфейс, но при разработке с таким подходом вы, скорее всего, окажетесь довольно много. – Magus

+0

+1 для перехода к ядерному – Bit

0

Точка interface предназначена для определения общей и подлежащей исполнению структуры для класса.

Преимущества в вашем примере не очевидны, потому что вы объявили только один тип IWeapon. Реальное преимущество возникает, когда вы начинаете создавать разные виды оружия.

IWeapon класса есть, чтобы определить, что вы ожидаете от каждого оружия, таким образом каждый класс оружия вы создаете, который наследует от IWeapon вынужден следовать этому.

В конечном счете, это предсказуемо с точки зрения того, что вы ожидаете от него с точки зрения методов. Тем не менее, все эти методы уникальны для каждого оружия.

Пример:

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

С, что на месте, я могу определить любое количество оружия, и каждый из них будет предоставлять мне с этим содержанием минимального класса. Реальное преимущество заключается в том, что каждый из них реализует эти методы своими уникальными способами.

Подумайте о интерфейсе, таком как шаблон для набора связанных классов.

+2

Вы также можете добавить достижения, когда дело доходит до тестирования и использования IWeapon в тесте, и не нужно настраивать те же тесты для винтовки и ручного пистолета. – Bit

+0

Некоторые из них могут быть свойствами. Просто добавленное примечание. – Magus

+0

@Magus Нет свойств в интерфейсе. – DonBoitnott

0

Предположим, у вас есть метод:

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

Теперь, если ваш интерфейс будет определяет следующим образом:

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

Ваш метод может принимать все виды оружия, не обращая внимания:

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

Интерфейс в схеме прототипа должен выглядеть следующим образом:

interface ICloneable 
{ 
    ICloneable Clone(); 
} 

Т.е. вы не используете интерфейс для маркировки своего класса в качестве оружия, вы используете его, чтобы отметить, что он имеет метод Clone, который можно использовать для создания копии.

Смежные вопросы