Вопросы при разработке иерархии ООП - PullRequest
1 голос
/ 05 июня 2010

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

Но я не знаю, это правильный способ проектирования? И какие недостатки могут возникнуть в неидеальной абстрактной иерархии. Я должен дать четкий пример для этого. Подумай о шахматах и ​​фигурах. Если мне нужно определить фигуры, такие как пешка, ферзь, король и т. Д. Посмотрите на диаграмму UML ниже.

http://i.stack.imgur.com/1VC22.png

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

Но я также могу разделить их по направлению, потому что некоторые фигуры могут идти в 8 направлениях, некоторые - в 4 направлениях, а некоторые - в 2 или 3 направления. Группировка их направленно вызывает некоторые новые вопросы. Где они будут в иерархии? они придут после скользящих занятий? Если это возможно, можно найти четыре направленные группировки по скользящим и не скользящим группам, и мы знаем, что невозможно наследовать по 2 классам. Так что для таких ситуаций мне приходится выбирать интерфейсы? если направления никогда не будут под обоими, так что можно использовать абстрактные классы. Это нормально, если я снова найду новую общую группу, которая не требует наследования от 2 классов, так что я могу определить ее по указаниям.

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

Но что может быть недостатком в создании слишком большой всеобъемлющей иерархии?

Может быть, в автозаполнении IDE может отображаться множество ненужных и странно названных абстрактных базовых классов, которые смущают других? какие могут быть другие недостатки?

Ответы [ 3 ]

2 голосов
/ 05 июня 2010

Способ слишком сложный для задачи. Вы переусердствовали с OO. Это означает, что вам придется заполнить 20 с лишним классов кодом. Вы должны действительно упростить это.

Подумайте об этом с точки зрения атрибутов (color, isUnderAttack) и поведения (перемещение). В этом случае вам нужен только один класс class ChessPiece, который имеет свойства для цвета и isUnderAttack. Затем вы можете использовать некоторую форму внедрения зависимости. Посмотрите, как будет выглядеть этот код:

public class ChessPiece
{
    public enum ChessPieceColor{White, Black}
    private IChessMove behavior;
    public ChessPiece(IChessMove behavior, ChessPieceColor color)
    {
        this.behavior = behavior;
    }
    public void Move()
    {
        behavior.Move();
    }
}

public interface IChessMove
{
    void Move();
}

public class KnightMove : IChessMove
{
    public void Move()
    {
        // code to perform the moving.
    }
}

public class Program
{
    static void Main()
    {
        ChessPiece knight = new ChessPiece(new KnightMove(), ChessPiece.ChessPieceColor.White);
    }
}

Тогда вы просто закодируете разные IChessMove для каждого типа фигуры. Очевидно, что вам нужно добавить больше информации к методам, чтобы он действительно работал, но он должен показать вам шаблон, который вы должны использовать здесь. Класс для каждого возможного предмета заходит слишком далеко, когда у многих общее поведение.

1 голос
/ 05 июня 2010

Но что может быть недостатком в создании слишком большой всеобъемлющей иерархии?

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

Это случается, хотя. Его очень сложно спроектировать с первого раза. Лучше не пытаться.

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

1 голос
/ 05 июня 2010

Хорошо ... Проблема в том, что наследственные иерархии хрупки - они могут быть легко бесполезны, например, в случаях, которые вы называете своими проблемами. Как вы предлагаете, вы можете спроектировать иерархию разными способами, но помните о принципе подстановки Лискова и, самое главное, не злоупотребляйте наследованием. Используйте его только при необходимости. Вы не должны использовать абстрактный класс и наследование только потому, что можете. Я не очень хорош в шахматах, но разные фигуры имеют разное поведение? Существует известный пример проблемы с абстракцией при создании иерархии наследования. Возьмите круг и эллипс, что является более абстрактным? Когда вы попытаетесь сделать один из них суперклассом другого, вы получите негибкий дизайн. Постарайтесь больше понять объектно-ориентированное программирование и старайтесь наследовать только тогда, когда нет другого выбора.

...