Правильное ОО моделирование соответствий - PullRequest
3 голосов
/ 22 мая 2009

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

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

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

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

Обновление : Ну, RailStations - это не вершины! Они?

Хорошо, давайте рассмотрим реальный код, как того требуют ответы. Позвольте мне моделировать человека с детьми. Это самая простая вещь, верно? Дети также должны знать своих родителей, поэтому у нас есть как двусвязное дерево. Чтобы упростить расформирование родителей и детей, я смоделирую связь между родителем и ребенком как отношение со свойствами parent и child.

Итак, я мог бы реализовать parent >> removeChild: возможно, вот так

removeChild: aChild
    (parent relationshipWith: aChild) disband.

Итак, родитель имеет набор отношений, а не детей. Но каждое отношение соответствует ребенку. Теперь я хочу сделать что-то вроде этого:

parent children removeAllSuchThat: [:e | e age < 12]

который должен удалить отношения и ребенка.

Здесь отношения и дети в некотором смысле соответствуют друг другу. Итак, что мне теперь делать? Не поймите меня неправильно, я полностью осознаю, что могу решить проблему, не вводя классов Relationship. Но на самом деле родители и дети действительно имеют общие отношения, так почему бы не смоделировать их и не использовать их, чтобы помочь расформированию двойных связей менее настойчиво?

Ответы [ 5 ]

3 голосов
/ 22 мая 2009

В вашей проблемной области разве станции не являются вершинами? В таком случае, почему бы не извлечь Station из Vertex?

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

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

2 голосов
/ 22 мая 2009

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

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

Как я понимаю вашу ситуацию, станция-вершина и наследование - это способ смоделировать это.

2 голосов
/ 22 мая 2009

Похоже, вы просто хотите, чтобы RailStation наследовал от Vertex (это отношение). См. руководство по Smalltalk по наследованию. Таким образом, если у вас есть граф RailStations, объект, используемый для работы (в общем) с графами вершин, будет обрабатывать вещи естественным образом.

Если этот подход не сработает, будьте более конкретны (желательно с реальным кодом).

1 голос
/ 03 июня 2009

Посмотрите на Славу, смотрите http://www.squeaksource.com/Fame.html

Мы используем специализированный подкласс Collection, который обновляет противоположный конец при добавлении или удалении элементов. Кроме того, вы можете пометить ваши классы с прагмами, чтобы аннотировать отношения. Эти прагмы используются фреймворком Fame для создания разных полезных вещей.

1 голос
/ 22 мая 2009

Наличие объекта Relationship - хорошая идея.

Я думаю, что уместным вопросом здесь является «как использовать его?».

Вероятно, классы Parent и Child расширяют один и тот же суперкласс Person, поэтому у них будут общие атрибуты, например, age.

В моей идее я вижу следующее: Родительский и Дочерний объекты должны знать друг друга, поэтому оба класса должны сохранять ссылку на одно и то же Отношение. Объект Relationship поддерживает отношение «один ко многим» между одним родителем и определенным числом детей и будет сохранять ссылку на каждый объект Person.

Таким образом, вы можете реализовать всю логику расформирования в объекте Relationshp, более или менее сложную, как вы хотите. Вы можете запросить объект Relationship, чтобы узнать, какие члены семьи соответствуют вашим требованиям, чтобы что-то сделать. Вы можете сделать отношения, чтобы распустить (и уничтожить) безопасно, так как он будет знать всех участников и попросит их разорвать ссылку, и тогда он будет готов уничтожить, или попросит кого-то из членов покинуть семью, сохраняя объект Relationship в живых.

Но это еще не все. Отношения должны быть действительно суперклассом, расширенными HierarchicalRelationship и PeerRelationship (или FriendRelationship).

Эта специализация позволяет вам иметь Parent (s) и Child (ren) для связи между другими иерархиями полностью обходным путем.

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

Извините за огромное количество метафор.

...