2017-02-15 8 views
3

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

  • Страна (из народа)
  • Людей

I имеют конкретизацию этих двух классов, например:

  • Страна: Франция и Италия
  • Люди: FrenchGuy и ItalianGuy

Страна абстрактный класс как список людей, как атрибут: peopleList: Люди

Как я могу гарантировать что Франция класс peopleList атрибут будет заполнена только с FrenchGuy и Италия с ItalianGuy, и сделать его последовательным?

Как я разработал это анти-шаблон?

enter image description here

Заранее спасибо за ваши ответы

+0

Вы перепутали «своего рода» с «является экземпляром» в вашем примере. Это огромный антипаттерн! –

+0

У меня могло бы быть время объяснить, как это сделать сегодня позже. Использование набора обобщений - красная селедка. –

+0

@ JimL .: _ Вы перепутали «своего рода» с «является экземпляром» в вашем примере.: Действительно, это мой пример, который не очень хорошо выбран. Франция и Италия в моем случае должны быть _специализация_, а не _instances_. Например, _France_ будет иметь метод _getCheese() _, а _Italy_ a _getPizza() _ – matt

ответ

1

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

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

redefinition example diagram

Я дам вам тур, что это UML диаграмма говорит нам:

  • Существует неназванная связь между Insurance Policy и Insurable Thing, который имеет два свойства: страхует и застрахованные по.Это говорит нам о том, что, в общем, каждый Insurance Policyстрахует один или более Insurable Things, и каждый Insurable Thing может быть застрахована любое количество Insurance Policies
  • Insurance Policy имеет два disjoint² специализации: Health Insurance Policy и Car Insurance Policy.
  • A Insurable Thing имеет две непересекающиеся специализации: Car и Person.
  • Неназванных ассоциация в верхнем имеет два специализированной ассоциацию с более конкретными ограничениями собственности:
    • Связи между Car Insurance Policy и Car обладает свойствами, которые переопределяют (т.е. затянуть) их допустимые типов.
    • У ассоциации между Health Insurance Policy и Person есть свойства, которые redefine (т. Е. Затяните) их разрешенные типы.

специализированные ассоциации и переопределения делают всю работу здесь. Если вам нравится, вы можете еще больше усилить множественность или даже изменить имена свойств³.


¹ Обратите внимание, что UML недавно был принят «точечную нотацию», что делает отсутствие точек на концах ассоциации неоднозначной. Префиксная нотация, навигационное свойство принадлежало классу на другом конце ассоциации. Нотация Post dot, навигационное свойство принадлежит ассоциации - за исключением того факта, что несколько инструментов поддерживают его, а те, которые делают, например MagicDraw, по умолчанию делят по умолчанию в вариантах проекта! Я лично нахожу точечную нотацию ужасной, поэтому этот пример ее не использует, что означает, что свойства принадлежат классу на противоположном конце его ассоциации.

² Disjoint означает, что ничто не может быть экземпляром обеих специализаций, которые позволяют использовать множество языков реализации, но реальный мир и UML сделать позволяют. Неполное означает, что могут существовать другие виды страховых полисов, которые мы не вызывали, и можно напрямую создать общий код Insurance Policy.

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

+0

Хорошо, спасибо Джим Л. за этот очень подробный ответ. С точки зрения реализации, я предполагаю, что это не так просто, как простое наследование или что-то вроде композиции или агрегации. Существует ли известный шаблон для получения такой структуры на уровне БД (через абстракцию ORM) и на программном уровне (без учета БД)? – matt

+0

Для ORM см. [Наследование классов] (https://martinfowler.com/eaaCatalog/classTableInheritance.html) или [Наследование бетонных таблиц] (https://martinfowler.com/eaaCatalog/concreteTableInheritance.html). Каждая таблица будет иметь свой собственный внешний ключ. Эта диаграмма UML чрезвычайно проста для реализации с использованием методов на языке OO, поэтому я не уверен, что еще сказать об этом. –

1

В принципе вы могли бы сделать, что с помощью Generalization Sets. Это гарантирует, что обобщения от Italy и Italian Guy (у вас есть только мужская страна?) Связаны, и таким образом вы будете иметь только «правильную» популяцию.

+0

_ «У вас есть страна только для мужчин?» _: Да, нет, женщина, без крика. Я не совсем понимаю, что описано в приведенной ссылке о наборе обобщений и [последующем примере] (http://www.uml-diagrams.org/examples/health-insurance-policy-domain-diagram-example .html). Как связь между, например, в моем примере _Italy_ и _Italian guy_ материализуется? Это то, что они называют ** типом власти **? – matt

+0

Вы можете ввести каждое обобщение в определенной стране (': France' и': Italy'). Вероятно, вам не нужны какие-либо ограничения. В качестве альтернативы вы перемещаете композицию до определенных классов в сторону от абстракций. –

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