2009-11-30 4 views
23

Я пытаюсь понять ориентацию объекта. Я понимаю это немного, но иногда я не на 100% понятен. Как вы решаете, что должно быть превращено в объект (небольшая часть объекта другого большого целого объекта) или то, что не стоит быть объектом, или, может быть, это должно быть просто свойство этого большого целого объекта?OOP: Когда это объект?

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

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

Благодаря

+23

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

+8

+1 для комментария, но я думаю, что легче получить первое понимание физических объектов и обобщить позже (может потребоваться бутылка вина или два ..;)) –

+0

Если вам нужна дверная ручка по какой-то причине, она должна * не * быть объектом. Большинство программ, которые имеют двери, вообще не докучают дверными ручками. –

ответ

2

Я бы посоветовал вам подумать о том, как вы собираетесь его использовать. Подумайте, какие операции вы будете делать с вашей «вещью», а затем подумайте, что было бы самым простым способом сделать это. Иногда легче будет сделать это свойством другого объекта, иногда легче будет сделать его новым объектом.

Нет универсального рецепта, может быть много факторов, которые делают одно решение лучшим. Просто рассмотрите каждый случай отдельно.

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

  • Вы хотите хранить много свойств в замочной скважине, как размер, форма, направление, граф булавки, будь то ключ может быть включен один раз или дважды, и т.д .;
  • На дверной ручке может быть более одной замочной скважины;
  • Вы хотите дать замочной скважине некоторые свойства только для чтения (например, заблокированы ли они или нет), а затем разрешить их модификацию только с помощью определенных методов (например, метод «разблокировки», который принимает «ключевой» объект в качестве параметров);
  • Скважины хранятся в отдельной таблице БД с одной замочной скважиной на каждую строку БД (тогда может иметь смысл сделать объект замочной скважины имитирующим структуру БД);
  • В вашей системе есть методы, которые будут реализованы элегантным способом, если они могут взять замочную скважину в качестве параметра;

Сценарии для создания его свойства противоположны:

  • Каждая дверная может иметь только один замочную скважину, и она имеет только один или очень мало свойств;
  • Скважины хранятся вместе с дверными ручками в БД;
  • Вы, как правило, не заботитесь о замочной скважине в одиночку, вы просто хотите, чтобы она была описательным свойством дверной ручки (например, есть ли она или нет);
4

Это зависит немного от объема использования. Чтобы пойти с вашим примером, если дверная ручка является важной частью и может (потенциально) использоваться на другой двери (или другой ручкой для «этого»), то это, вероятно, должен быть объект.

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

2

Учебный способ принятия решения о гранулярности объекта заключается в достижении единства.

Если большинство методов вашего объекта работает с большинством полей объекта, то объект достаточно мал (для заданного значения «most»).

Объект почти никогда не бывает слишком маленьким.

1

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

30

Как всегда, ответ несчастлив: это зависит ...

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

Возьмите автомобиль и его колеса - если вы моделируете город и хотите какой-то трафик, вы можете создать класс «Автомобиль» с атрибутом «numberOfWheels». Но если вы разрабатываете автомобили, то, скорее всего, вы захотите создать класс «Колесо» и добавить четыре из них в класс «Автомобиль».

Правило большого пальца:

  1. , если это то, что вы думаете о том, имеет более одного атрибута, определить класс
  2. , если это то, что вы думаете о том, имеет некоторое поведение , определить класс
  3. , если это то, что вы думаете о том, может расти или быть продлен, определить класс
  4. , если это то, что вы думаете о том, должен быть сортируется, сопоставимыми, определить класс
  5. Если вы не уверены, определите класс;)

Редактировать

Потому что вы подчеркнули «многоразового использования» аспект: я не думаю, что это аспект для принятия решения о том, чтобы использовать класс или нет. Подумайте о простом счетчике, целочисленном значении в цикле for. Вы будете использовать эту концепцию сотни раз, но я уверен, вы никогда не подумаете об упаковке этого плохого маленького int в класс «Counter» - только потому, что вы используете «концепцию счетчика» несколько раз.

+4

+1, +1 снова, если бы я мог только для последнего абзаца. –

+4

Автомобиль и пример его колеса отличный :) – Lipis

+1

+1 для автолюбителя аналогичный – Gazzonyx

1

Другой способ взглянуть на то, является ли дверная ручка взаимозаменяемой. Я сделал бы дверную ручку отдельным объектом, который является собственностью на двери. Один вопрос заключается в том, хотите ли вы сделать дверную ручку приватным классом, если только дверь может иметь эту ручку. Я лично предпочитаю не использовать частный класс здесь, но это законная возможность. Используя отдельный объект как свойство на двери, вы можете теперь перемещать этот экземпляр ручки с одной двери (экземпляра) на другую (например, обменивать ручки с одной двери на другую в вашем доме).

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

Я надеюсь, что это помогло немного разъяснить ваше замешательство.

1

В целом, если вам нужна дополнительная информация, а только одна вещь вещь (не только состояние ручки, но и ее цвет, точное расположение, имеет ли он ключевой паз, возможность изменения его состояния/поведение и т. д.), затем создайте объект. Таким образом, когда вы не можете хранить всю информацию, которую дверь должна знать о ручке в простых String, Number или Boolean, тогда сделайте это полноправным Knob.

Как и везде, у вас также есть «угловые шкафы». Я часто вижу это с парами. Две пророчества, которые связаны друг с другом, но обычно ни с чем другим. Они не всегда группируются в отдельный объект реального мира. Например, sortDirection и sortField. Независимо от того, принадлежат ли они в своем собственном объекте, зависит от того, что представляет собой родительский объект. Является ли это сортируемой реализацией List? Ладно, держи его там. Это Door? Ну, я бы, возможно, внедрил его.

2

Это объект, если вам нужно подумать об этом как о объекте.

То есть, если вам нужна абстракция.

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

1) Может быть boolean собственностью, если Вам просто нужно знать, что ваша дверь имеет его:


class Door 
{ 
    bool HasKeyHole; 
} 

2) Может быть парой координат, если вы просто хотите, чтобы сделать вашу дверь и положить кружок на месте ключевого отверстия


class Door 
{ 
    Point KeyHoleCoordinates; 
} 

3) Может быть специально определен класс KeyHole, если вы хотите, чтобы инкапсулировать логику и некоторые свойства ключевого отверстия и работать вместе с ними, вероятно, передавая их вокруг, или позволять взаимодействие с Key


class KeyHole 
{ 
    Point Coordinates; 
    bool OpensWithKey(Key key); 
} 

class Door 
{ 
    KeyHole Hole; 
} 

12

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

Объект представляет собой структуру данных в сочетании с набором методов, которые могут работать с этой структурой данных. Свойства объекта сохраняют состояние объекта, а методы работают с состоянием.

Какое состояние системы вы пытаетесь моделировать? Это находится в дверях, ручке или какой-то комбинации этих двух?

Существуют некоторые методологии, которые пытаются четко определить объектную модель перед началом кодирования. Другие методологии (например,g, TDD) позволяют объектной модели появляться в процессе кодирования. В вашем случае я бы рекомендовал кодировать некоторые приложения малого и среднего размера, используя TDD, чтобы вы могли видеть преимущества и недостатки различных шаблонов. Существует редко один «правильный» способ моделирования конкретной ситуации, но некоторые модели гораздо проще в использовании и понимании, чем другие; распознавание шаблонов, которые применяются к ситуации перед вами, приходит с опытом.

Итак, нижняя строка: сделайте много моделей. Думайте о доменах приложений, моделируйте их и код. При этом все станет намного яснее. Сделайте песочницу и войдите.

+0

Согласен. Я задал вопрос, требующий более точных аналогов, чем уклонения, мяу и аналогий. – netrox

+0

Объекты не обязательно являются структурами данных. ** Список ** в .Net не обязательно реализуется как список в памяти. Объекты - это абстракция структур данных. – user

0

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

Чрезмерное использование объектов будет сказать:
Там есть объект для блокировки, есть цвет объекта для каждого цвета («коричневатого» для двери, «серебро» для замка и ручки), и материалы объекты («дерево» для двери и «сталь» для ручки и замка)
Здесь вы можете увидеть разницу между классом и объектом:

класс является абстрактным (не в смысле языка программирования) форма чего-то. Вы можете направить что-то в качестве ручки, и все знают, что это такое. Вы знаете, что ручка имеет цвет и материал.

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

Но есть большая проблема в программировании объектов и объектов реальной жизни. Эти базовые примеры помогают понять основные принципы ООП. Вы должны освободиться от этого очень скоро!

(Для тех, кому любопытно: Является ли прямоугольник квадрат или квадрат прямоугольник?)

1

Пока объект имеет только одну цель/ответственность не должна быть разделена больше (если это не слишком большой, чего не должно быть).

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

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

0

Все - объект. Иногда вы просто используете примитивную переменную (int) для представления объекта, а иногда вы создаете структуру данных (struct/class). И, естественно, некоторые объекты являются частями других объектов.

Итак, да, если вам нужно сделать в своем коде что-то с той частью, где вы вставляете ключ, он также должен быть объектом вашего кода. Он может быть представлен только string Keyhole и может быть представлен class Keyhole, он может быть независимым объектом и может быть частью class DoorKnob, но в любом случае это будет объект.

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

1

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

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

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

1

Существует теория, а затем есть практика ... а затем вы, как инженер-программист, пытаетесь сбалансировать их обоих.

В теории вы должны делать объекты почти все, пока не упадете до наименьших возможных элементов, примитивных типов (булевых, строковых, целых и т. Д.). Ну .. это довольно упрощенно, но с этим один редко идет не так ...

что ...

пока вы не получите, чтобы создать (то есть код классы) вещь.

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

Мой подход обычно начинается с одного большого класса (уродливый, но он быстрый для кода, и я могу быстрее получить рабочий прототип). Затем, если мне когда-либо понадобится определить корректировки или новое поведение или повторно использовать часть целого, тогда я создаю элемент smalle и реорганизую большой, чтобы использовать меньший, вместо определения его собственных атрибутов.

Например. Я кодирую класс двери, и оттуда я могу создать (создать экземпляр) столько дверей, сколько захочу, но они все одинаковы и ведут себя одинаково. Теперь я понимаю, что мне нужно также определить окна, вращающиеся вокруг шарниров ... Подождите минуту ... у дверей тоже есть петли. Здесь я создаю класс шарнира, который может использоваться как дверью, так и окном, и удалять все, что у меня было раньше, чтобы определить шарнир в классе дверей. Затем продолжайте работать, пока не столкнетесь с ситуацией, когда я могу повторно использовать некоторые части для нескольких объектов (ручку, фрейм и т. Д.).

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

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

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

в любом случае ... мой два цента, я надеюсь, что это поможет.

10

При принятии решения, если что-то есть объект или нет, спросите себя, если она имеет следующий ...

государственный

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

Поведение

ли объект на самом деле сделать что-то в домене? Например, это просто полный аксессоров, которые манипулируют структурой или записью.

Идентичность

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

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


Прежде всего, дон» t беспокоиться об этом ...

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

3

Как старое клише говорит, что «объекты должны быть существительными». Каждый раз, когда вы думаете о вещь, это, вероятно, должен быть объект. Каждый раз, когда вы думаете о действии, вероятно, это функция или метод.

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

+0

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

+0

Как я уже сказал, это далеко не полный. Когда я был на уровне, когда мне нужно было спросить цель ООП, я бы не знал о коде и состоянии, соединении или модульном тестировании. Таким образом, требуется некоторое упрощение. –

0

Все - объект. От кварков над электронами, атомами до элементов, пыли, людей, автомобилей, мира и вселенной.

Даже мысли, идеи или чувства являются объектами.

(До сих пор для очевидного ответа)

Далее в «решить, что deservers быть объектом»; Я alawys к нему так просто, как , он должен вести себя в любом случае и будет использоваться не один раз.

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

Кроме того; будет ли он повторно использоваться другими вещами? (Объекты, проекты, программы и т. Д.). Это те мысли, которые у меня есть, когда я решаю, что должно и что не может быть объектом.

Но, как я сказал выше, вопрос тривиален, так как все - это объект сам по себе.

1

Я ответил на это уже в another question

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

Не верьте тому, что книги/школы Java учат об объектах; они лгут.

Просто напишите то, что получает работу, даже если это некрасиво, а затем непрерывно рефакторинг:

Но :

Если вы не до конца с массивными (и бесполезными) иерархиями классов, то вы проделали хорошую работу, создавая элегантный и чистый код.

Помните: ООП - это средство, а не конец.

1

Хороший старый Plato уже был ответ (вид) ...

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

+1

Платон - истинный изобретатель объектно-ориентированного мышления;) –

1

Все быть превращен в объект.

ИМО, ответ на ваш вопрос - вопрос Является ли поведение ключевого отверстия, необходимое для того, чтобы моя модель двери была точным представлением?

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

Смежные вопросы