Вопрос

У меня была дискуссия на работе, касающуюся «наследство в области доменов, усложняет жизнь застройщиков». Я программист OO, поэтому я начал искать аргументы, которые наследство в области домена ослабит жизнь застройщика на самом деле вместо переключателей по всему месту.

Что я хотел бы видеть, это это:

class Animal {

}

class Cat : Animal {

}

class Dog : Animal {

}

Что говорит другой коллега:

public enum AnimalType {
    Unknown,
    Cat,
    Dog
}

public class Animal {

    public AnimalType Type { get; set; }

}

Как я могу убедить его (ссылки ДОБРО ПОЖАЛОВАТЬ ) что иерархия класса будет лучше, чем иметь свойство Enum для такого рода ситуаций?

Спасибо!

Это было полезно?

Решение

Вот как я причин об этом:

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

Использование наследства для вещей, таких как:

Fireman <- сотрудник <- человек неверно.

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

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

Чем более правильный способ отдать лицу класс список ролей. Каждая роль представляет, например, занятость с промежуткой времени.

например

freddy.Roles.Add(new Employement( employmentDate, jobTitle ));

Или если это накладки:

freddy.CurrentEmployment = new Employement( employmentDate, jobTitle );

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

Тем не менее, все мои бродяги до сих пор не ответили, если вы должны использовать иерархию Enum или Tyer для JobTitle.

Чистым в MEM OO я бы сказал, что более правильно использовать наследство для JobTitles здесь.

Но если вы делаете сопоставление O / R, вы можете в конечном итоге с небольшим количеством модели данных переключателя позади сцен, если Mapper пытается сопоставить каждый тип Sub Type на новую таблицу. Таким образом, в таких случаях я часто хожу на подход Enum, если нет реального / сложного поведения, связанного с типами. Я могу жить с «если type == Jobtitles.firman ...» Если использование ограничено, и это делает вещи легкими или менее сложными.

Например, дизайнер Framework Entity Framework 4 для .NET может только набрать каждый тип Sub в новую таблицу. И вы можете получить уродливую модель или много присоединений, когда вы запрашиваете вашу базу данных без какой-либо реальной выгоды.

Однако я использую наследство, если тип / роль статичен. например, для продуктов.

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

Так что короче говоря, это зависит ;-)

Кроме того, в конце дня вы, скорее всего, покончите с большим количеством выключателей в любом случае. Допустим, вы хотите редактировать «продукт», даже если вы используете наследование, у вас, вероятно, у вас будет такой код:

Если (продукт - книга) Ответ. Изменен ("~ / editbook.aspx? ID" + product.id);

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

Другие советы

Перемычки хороши, когда:

  1. Набор значений фиксирован и никогда не или очень редко меняется.
  2. Вы хотите иметь возможность представлять союз ценностей (то есть сочетание флагов).
  3. Вам не нужно прикрепить другое состояние каждому значению. (Java не имеет этого ограничения.)

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

  1. Статизм убедитесь, что все поведение типа обрабатывается. Например, если вам нужны все животные, чтобы иметь возможность Bark(), изготовление Animal классы с абстрактным Bark() Метод позволит компилятору проверить вам, что каждый подкласс реализует его. Если вы используете enum и большой switch, это не гарантирует, что вы обрабатывали каждый случай.

  2. Вы можете добавлять новые случаи (типы животных в вашем примере). Это можно сделать через исходные файлы и даже через границы пакета. С помощью Enum, как только вы объявили это, это заморожено. Открытое расширение является одним из основных сил OOP.

Важно отметить, что пример вашего коллеги не является прямой оппозицией для вашего. Если он хочет, чтобы тип животного был выставленным имуществом (что полезно для некоторых вещей), вы все равно можете сделать это без использования Enum, используя Тип объекта шаблон:

public abstract class AnimalType {
    public static AnimalType Unknown { get; private set; }
    public static AnimalType Cat { get; private set; }
    public static AnimalType Dog { get; private set; }

    static AnimalType() {
        Unknown = new AnimalType("Unknown");
        Cat = new AnimalType("Cat");
        Dog = new AnimalType("Dog");
    }
}

public class Animal {
    public AnimalType Type { get; set; }
}

Это дает вам удобство enum: вы можете сделать AnimalType.Cat И вы можете получить тип животного. Но это также дает вам гибкость классов: вы можете добавить поля для AnimalType Чтобы сохранить дополнительные данные с каждым типом, добавить виртуальные методы и т. Д. Более важно, вы можете определить новые типы животных, просто создавая новые экземпляры AnimalType.

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

Наличие enum - это как бросать вечеринку для всех Open/Closed Principle is for suckers люди.

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

Самое главное ой означает моделирование реальности. Наследование дает вам возможность сказать, что Cat - это животное. Животное не должно знать, если его кот теперь кричит, а затем решите, что оно должно быть, чтобы мяу и не лаять, инкапсуляция там побеждается. Меньше кода, как сейчас вам не нужно делать, если вы, как вы сказали.

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

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

Но если вы программируете, используете много разных объектов (разные классы), и могут добавлять новые классы, в будущем, лучше попробуйте наследование.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top