Объектно-ориентированное программирование - беспорядок дизайна класса

Перечисление флагов может работать также, я думаю, если Вы делаете его перечислением байта:

[Flags] enum PesHeaders : byte { /* ... */ }
11
задан Kenny Linsky 16 July 2012 в 14:50
поделиться

12 ответов

У вас проблема с дизайном - как вы правильно заметили, Eat () не имеет очевидного смысла как член Fruit. С другой стороны, атрибут «съедобный» имел бы больше смысла. Как и событие «onEaten» и т. Д. То, что раскрывают ваши классы фруктов / яблок (и какие другие объекты имеют смысл в вашей модели), зависит от множества других факторов, включая то, что вы пытаетесь достичь. с этими конструкциями в вашем приложении.

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

На мой взгляд, объектно-ориентированная декомпозиция проблем - это то, с чем программисты обычно очень плохо справляются. Я не знаю, сколько раз я

12
ответ дан 3 December 2019 в 03:04
поделиться

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

Вам нужно найти основную абстракцию вашей реальной проблемы, а не просто копировать существительные в иерархии объектов .

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

Я считаю, что ООП больше связано с пробелами - кем вы являетесь исключение важнее.

8
ответ дан 3 December 2019 в 03:04
поделиться

Я думаю, вам следует прочитать принципы SOLID, это вам очень поможет. http://www.lostechies.com/blogs/chad_myers/archive/2008/03/07/pablo-s-topic-of-the-month-march-solid-principles.aspx

5
ответ дан 3 December 2019 в 03:04
поделиться

Если предположить, что вы, скажем, пишете симулятор голодных людей, тогда, я думаю, было бы гораздо разумнее, как вы говорите, иметь Human :: Eat (Fruit f) функция. У вашего Fruit может не быть методов, поскольку Fruit сам по себе мало что делает, но у него может быть свойство калорий, и так далее.

1
ответ дан 3 December 2019 в 03:04
поделиться

Лучше передать фруктовый объект к человеческому объекту, у которого есть Eat () function?

Да.

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

0
ответ дан 3 December 2019 в 03:04
поделиться

Вы правы, что, вероятно, eat () будет методом человека, млекопитающего или fruitFly. Сам плод, вероятно, не имеет поведения и, следовательно, не имеет методов.

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

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

0
ответ дан 3 December 2019 в 03:04
поделиться

Я склонен думать о:

Является ли

Имеет

Итак, яблоко - это плод, поэтому наследование имеет смысл.

Но фрукт имеет ( is) съедобное, может иметь смысл, но это показывает, что это свойство фруктов, а не действие (метод).

Например, у вас может быть незрелое яблоко, которое не будет съедобным (съедобным), поэтому вы можете затем установить это свойство.

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

Теперь Имеет для композиции. Итак, у яблока есть семя, это будет означать, что семя не расширяет яблоко, но яблоко будет иметь набор семян.

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

0
ответ дан 3 December 2019 в 03:04
поделиться

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

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

Теперь вы можете задать следующие вопросы о своем объекте:

  • «Что делает респонсибилитес у моего объекта есть в системе ? "
  • " Этот объект отвечает за выполнение xxx , или xxx должен быть обязанностью другого объект? "
  • "
0
ответ дан 3 December 2019 в 03:04
поделиться

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

Может быть, больше похоже на «соотнесение» их с объектами реальной жизни, где это применимо.

Следует ли передать фруктовый объект человеческому объекту, у которого есть функция Eat ()?

Да, или чему-то более общему, чем человеческий.

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

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

0
ответ дан 3 December 2019 в 03:04
поделиться

Что-то из класса Herbivore будет иметь функцию Eat, как и что-то из класса Carnivore, но у каждого Eat будут различные ограничения на то, какой аргумент может быть передан функции Eat. Fruit - это то, что съедено , поэтому он будет передан в качестве аргумента в Herbivore.Eat (), тогда как вам нужно передать объект типа Hamburger в Carnivore.Eat () и вызвать исключение если бы Hamburger был передан в Herbivore.Eat ().

Но на самом деле, я не думаю, что ООП позволяет нам моделировать программные объекты, чтобы они были такими же, как объекты реальной жизни. Я обнаружил, что большая часть моего дизайна ООП работает с довольно абстрактными объектами и только в отношении системы, частью которой они являются. Если бы я написал систему проверки / проверки библиотеки, Я бы смоделировал Книгу с точки зрения ее административных свойств и функций - я бы не моделировал ее как коллекцию объектов Page, и я сомневаюсь, что я бы даже определил что-либо вроде метода Read (), хотя это основная цель наличия книга в первую очередь. Роль объекта Book в системе определяет мой дизайн гораздо больше, чем то, что делают с книгами в реальном мире.

3
ответ дан 3 December 2019 в 03:04
поделиться

Насколько близко, в целом, должны программироваться объекты, отражающие реальные объекты.

Немного, только достаточно.

Абстракция - одна из основных характеристик ООП. Вам не нужно иметь все атрибуты / методы объекта, чтобы использовать его.

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

Вся суть в объектах состоит в том, чтобы иметь данные и функции, которые что-то делают с этими данными, в одном месте.

Итак, в вашем классе фруктов я бы лучше имел что-нибудь вроде Цвета или указание, будет ли оно съедено. Например:

 Fruit
     + color : Color
     - isMature : Boolean

     + canBeEaten() : Boolean
          return isMature

Таким образом вы можете создавать разные фрукты

 apple = Fruit()
 appe.color = Color.red
 out.print( "Can this fruit be eaten? %s ", apple.canBeEaten() )

 orange = Fruit()
 orage.color = Color.orange
 out.print( "Can this fruit be eaten? %s ", orange.canBeEaten() )

И т.д.

Если вы видите, что атрибуты (цвет и isMature) хранятся внутри объекта. Таким образом, вам не нужно отслеживать их состояние извне.

Что касается наследования, это имеет смысл только тогда, когда вам нужно добавить новое поведение к какому-либо методу, и да, методы относятся к атрибутам или характеристикам объекта. Как вы указываете, fruit.eat () не имеет особого смысла.

Но рассмотрите способ получения сока из фруктов.

Fruit
    + getJuice(): Juice

Apple -> Fruit
     + getJuice(): Juice
         // do what ever is needed internally to create the juice

Orange -> Fruit
    + getJuice(): Juice
        // here, certainly the way to get the juice will be different
0
ответ дан 3 December 2019 в 03:04
поделиться

Большинство человеческих языков следуют структуре предложения (для простых утверждений) Subject Verb Object

В ООП-языках, таких как c ++, не совсем иронично, объект - это объект, и он идет первым, поэтому нормальный порядок меняется на противоположный:

Итак, это «основной» шаблон в c ++: -

object.verb( subject );

Это на самом деле чушь. Большинство классов разработаны с интерфейсом subject.verb (object). Знание SVO, тем не менее, позволяет проверить, был ли интерфейс класса спроектирован так, чтобы быть правильным (в данном случае это не так).

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

0
ответ дан 3 December 2019 в 03:04
поделиться