2016-06-02 3 views
1

Я читал это wiki article о составе над наследованием, и в примере они использовали абстрактный класс. Предположим, вы хотели избежать полного использования абстрактных классов и использовать только конкретные классы. Я хочу знать, мой пример - правильное использование композиции. Предположим, у меня есть следующий интерфейс IGameobject.Композиция над наследованием - избегать абстрактных классов

public interface IGameObject 
    { 
     string Name {get;} 
    } 

и follwing интерфейс оружие:

//Note the IGameObject getter 
    public interface IWeapon 
    { 
     int Damage {get; } 
     IGameObject gameObject {get;} 
    } 

Обычно, в моей игре, оружие есть- IGameObject. Однако, учитывая, что мы используем композицию, согласно статье wiki, это имеет отношение.

Теперь, я мог бы сделать это при создании объекта Sword:

public class Sword : IWeapon 
{ 
     private IWeapon weaponObject; 

     public Sword(IWeapon weapon) 
     { 
      this.weaponObject = weapon; 
     } 

     public int Damage 
     { 
      get 
      { 
       return this.weaponObject.Damage; 
      } 
     } 

     public IGameObject gameObject 
     { 
      get 
      { 
       return this.weaponObject.gameObject; 
      } 
    } 

}

теперь я могу хранить свой меч в коллекции, например, список:

List<IWeapon> weapons = new List<IWeapon>(); 
weapons.add(swordObj) 

и все еще имеют доступ к моему IGameObject.

Теперь у меня есть 3 вопроса:

  1. ли я правильно реализовать состав?
  2. Должен ли мой класс Sword реализовать интерфейс IGameObject?
  3. Как хорошо, что мой IWeapon содержит IGameObject getter? (Причина, если хранить его в качестве IWeapon, без IGameObject добытчика, то как бы я получить подробную информацию о IGameObject?)
+1

Это выглядит очень странно - ваш класс «Sword» - это всего лишь обертка вокруг «IWeapon». – Lee

+0

Есть ли причина, по которой вы избегаете методов добавления поведения на своих интерфейсах и придерживаетесь свойств? –

+3

Это не имеет. Это - потому, что один и тот же объект имеет несколько аспектов. Это не поддается составу. Состав не лучше наследования. Это для разных вещей. – usr

ответ

5

композиция против Наследование является очень важным принципом для понимания, однако, как и любой принцип, он имеет положительный эффект только при правильном применении.

C vs Я думал, потому что разработчики «отправились в город» на ООП, особенно в таких языках, как C++, где допускается множественное наследование. Как вы можете себе представить, все шло довольно быстро, по дизайну.

Этот принцип можно легко сформулировать следующим образом: Мы, как разработчики, работающие на OOD, хотим моделировать отношения реального мира таким образом, который больше всего напоминает домен, который мы хотели бы имитировать, поэтому нам нужно посмотреть на эти отношения тщательно и тщательно.

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

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

Вот пример того, как C против я могу применить в домене:

interface IGameCharacter 
{ 
    ICollection<IWeapon> Weapons {get;} 
    ICollection<IGameCharacter> Party {get;} 
} 
+2

+1 для «C vs Я думал о потому что разработчики «отправились в город» на ООП. Я вижу историческую параллель между тем днем, когда ООП распространяется, и сегодня, когда функциональное программирование становится более популярным. Древний гуру ООП обещал и омрачил довольно простую механику ООП в научный миф. Через некоторое время люди выяснили способы создания рабочих систем ООП и разработали лучшие практики. Тем не менее, то, что работало тогда, по-прежнему работает сегодня: начните с ваших случаев использования и поверхности вашей подсистемы, а затем реализуйте по своему усмотрению. Хорошо определенные подсистемы поддерживают вашу систему разумно. – BitTickler

+0

@BitTickler. Пятно на. –

+0

@EyalPerry - Только один вопрос, все в порядке, если у моего IWeapon есть гейтер IGameObject? Итак, когда я реализую свой IWeapon, мне также нужно вернуть IGameObject? –

0

Что вы использовали здесь называется дизайн декоратор.Вы создаете новый класс, который расширяет некоторые суперклассы (IWeapon). Этот класс называется декоратором (Меч). Класс содержит объект того же типа, что и суперкласс - этот объект называется decoratee (weaponObject). Часть ответственности декоратора передается декоратору. На практике это означает, что декоратор вызывает по крайней мере один из методов decoratee в одном из своих алгоритмов (в вашем случае decoratee используется как для Damage, так и для gameObject).

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

Другой вариант будет подклассифицировать decoratee и наследовать желаемое поведение, но это вводит другие проблемы, связанные с подклассификацией (жесткая связь, наследующая какое-то нежелательное поведение в дополнение к желаемому поведению, выставляя вещи из декоратора, которые не должны подвергаться воздействию к декоратору и т. д.). Если вам нужны преимущества композиции, вы должны реализовать шаблон декоратора (или аналогичный шаблон) вместо подкласса. Имейте в виду, однако, что конкретный тип декоратора может измениться во время выполнения, и именно этот тип определяет, какое поведение вы получите в своем классе декоратора. Это может быть очень полезно для поддержки изменения поведения во время выполнения, но это также то, о чем вы должны знать при реализации шаблона.

Теперь, в зависимости от того, является ли шаблон декоратора правильным выбором в этой ситуации, я предлагаю вам следующий вопрос: хотите ли вы, чтобы ваш класс Sword (ваш декоратор) использовал какое-либо поведение из другого подкласса IWeapon (ваш decoratee) и хотите ли вы изменить это поведение во время выполнения? Если вы можете ответить «да» на этот вопрос, образец декоратора хорошо подходит.

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