Принцип Open-Close о новых возможностях - PullRequest
0 голосов
/ 15 октября 2018

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

public abstract class Player
{
    public string Name { get; set; }
    public int Level { get; set; }
}

public sealed class Fighter : Player { /* ... */ }
public sealed class Warrior : Player { /* ... */ }

Этот код работает отлично, вы сделали первый выпуск, все в порядке.
Теперь вы хотите добавить некоторые функции, такие как игрок может надеть кольцо .Принцип открытия-закрытия гласит: открыто для расширения, близко к модификации .Как я могу реализовать тот факт, что у моих игроков могут быть кольца, если я не должен изменять этот класс?

Ответы [ 2 ]

0 голосов
/ 15 октября 2018

Вы можете изменить класс Player, добавив новые методы и поля. открыто для расширения .Но если у вас уже есть некоторые методы, такие как Jump или Fight, и вы хотите изменить их - это нарушает принцип.

Представьте себе, у вашего класса Fighter есть метод Fight(), и он использует толькоголые руки:

public Fighter() : Player
{
  ...
  public virtual void Fight()
  {
    //use bare hands
  }
}

Если вы хотите, чтобы Fighter сражался палкой (например), вам не следует изменять исходный метод Fight(), но добавить другой класс, такой как FighterWithStick : Fighter и метод переопределения Fight()там:

public FighterWithStick() : Fighter
{
  ...
  public override void Fight()
  {
    //use stick
  }
}
0 голосов
/ 15 октября 2018

Сначала подумайте, почему такое правило может быть полезным.Закрыто для модификации, открыто для расширения.Это имеет смысл для библиотек или кода, которые должны быть обратно совместимы.Подумайте об этом примере:

Я написал библиотеку "BestLibrary", которая предоставляет интерфейс:

namespace BestLibrary
{
    public interface GoodStuff
    {
         Goodies GiveMeGoodStuff();
    }
}

Но в следующем выпуске я хочу решить, что Goodies дать на основепараметр, поэтому я изменяю интерфейс на:

namespace BestLibrary
{
    public interface GoodStuff
    {
         Goodies GiveMeGoodStuff(GoodiesType type);
    }
}
public enum GoodiesType { All, Type1, Type2 }

Теперь каждый , кто использует мою библиотеку, должен исправить их код, потому что их проекты прекратят сборку.Это тормозит принцип Open / Closed.Вместо этого я должен сделать другой метод, такой как:

namespace BestLibrary
{
    public interface GoodStuff
    {
         Goodies GiveMeGoodStuff();
         Goodies GiveMeGoodStuff(GoodiesType type);
    }
}

Здесь я ничего не изменил.Старый код все еще работает.Кто-то хочет случайных Goodies?Они все еще могут получить это.Я расширен GoodStuff интерфейс с дополнительным методом.Таким образом, все компилируется, и люди могут использовать новые функциональные возможности.

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

...