Как улучшить дизайн программы с учетом интерфейсов и абстрактных классов? - PullRequest
0 голосов
/ 02 апреля 2019

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

Рассмотрим следующий дизайн:

  1. Базовый класс ChessPiece, для которого также определены несколько дочерних классов
  2. Некоторым типам фигур требуется запись, если они уже были перемещены (а именно Pawn, Rook, King): свойство bool HasMoved
  3. Тип фигуры, который как King, не может быть захвачен ; все остальное может быть: bool IsCaptured свойство

Проблема заключается в конфликте между # 2 и 3 (нет проблем, если я реализую только один из двух) из-за производного класса King, который распространен в # 2 и 3.

В идеале должны быть реализованы оба абстрактных класса CapturablePiece и MoveRecordedPiece, которые оба наследуют от ChessPiece. Но C # не допускает множественное наследование классов , и именно здесь вступают интерфейсы.

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

// needed type-check
ChessPiece piece;
// some calculations...
if (piece is ICapturablePiece)    // or using the 'as' keyword
//or...
if (piece is IMoveRecordedPiece)
// which in the case of non-conflicting abstract classes,
// this is easily doable and valid because of
// inheritance to the base class

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

Версии абстрактного класса по-прежнему предпочтительнее - CapturablePiece и MoveRecordedPiece, поскольку его базовый тип - ChessPiece, и я уверен, что эта логика - " is-an " вместо « can-do » (как указано в ссылке выше).

Мой вопрос теперь будет: Как бы я мог улучшить дизайн , учитывая:

  1. Тот факт, что вы не можете наследовать несколько классов, а интерфейсы не могут ничего наследовать.
  2. Преимущество абстрактных классов над интерфейсами
  3. Блок кода, где требуется проверка типа

EDIT:

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

1 Ответ

0 голосов
/ 02 апреля 2019

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

Это позволяет вам красиво отделить ваш код.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...