Проблема понимания ассоциации UML
Я уже некоторое время использую UML и прочитал несколько статей, книг, форумов по этому поводу, но до сих пор не ДЕЙСТВИТЕЛЬНО понимаю, когда два класса должны быть связаны линией ассоциации (простая линия или стрелка (или это не так) тот же самый?)). Я приведу три примера - можете ли вы сказать мне, какой из этих двух классов будет в этих отношениях?
1.
//a field of OtherClass
public class MainClass
{
private OtherClass other;
}
2.
//method argument
public class MainClass
{
public void Action(OtherClass other)
{ }
}
3.
//method return value
public class MainClass
{
public OtherClass Action()
{ }
}
4.
//used inside a method
public class MainClass
{
private Something something;
public void Action()
{
OtherClass other = something.GetOtherClass();
}
}
4 ответа
Прежде всего, стрелка представляет судоходность ассоциации. Одиночная стрелка означает однонаправленное отношение, в этом случае только целевой класс знает о целевом классе. Стрелка на обоих концах означает двунаправленное отношение, где оба класса знают друг о друге. Если стрелок нет, связь может быть либо двунаправленной по умолчанию, либо подавлена для удобства чтения. На практике вы должны рисовать стрелки только тогда, когда вы хотите подчеркнуть направление ассоциации.
Когда дело доходит до вашего второго вопроса, только первый случай описывает (однонаправленную) связь между MainClass
а также OtherClass
, Ни аргументы, ни возвращаемые значения не подразумевают ассоциацию в смысле UML (хотя оба подразумевают зависимость). В последнем примере есть связь между MainClass
а также Something
класс через something
приписывать. Как правило, вы должны искать ассоциации в атрибутах.
Обратите внимание, что существует концепция dependency
в UML, и он представлен пунктирной линией.
Pozdrowienia!
Редактировать: переписать ответ после обсуждения в комментариях (спасибо chimp за то, что он указал на то, что я упустил в Примере 4)
Пример 1: OtherClass является атрибутом MainClass и, таким образом, моделируется как ассоциация.
Примеры 2 и 3: OtherClass упоминается в определении класса, хотя и не хранится в атрибуте, поэтому является зависимостью.
Пример 4: класс Something является атрибутом и, следовательно, ассоциацией, а ссылается на OtherClass, который не хранится в атрибуте, и поэтому является зависимостью.
В UML зависимости и ассоциации являются типами отношений и не являются строго связанными (кроме как через общий супертип), хотя, по моему мнению, ассоциация подразумевает зависимость.
Ассоциации обозначены линией между двумя классами с кратностями на каждом конце. Навигация обозначена стрелками, показывающими, какой класс знает о каком (например, класс A ___> Класс B означает, что A осведомлен о B, но не наоборот). Навигация в обоих направлениях показана стрелками на обоих концах. Там, где стрелок нет, обычно безопаснее не делать предположений о судоходстве, если не указано иное.
Зависимости обозначены пунктирной линией со стрелкой от зависимого класса (клиента) к классу, от которого зависит (поставщик) (например, A ----> B означает, что A зависит от B). Зависимости показывают, что на класс ссылаются в какой-то момент, и как таковой клиент зависит от операций, предоставляемых поставщиком, но он не указывает, как на него ссылаются (в отличие от ассоциации, которая предлагает ссылку, сохраненную в атрибуте).
Ассоциация представляет два или более связанных свойства.
В примере 1 MainClass имеет свойство типа OtherClass. Если OtherClass имеет явное свойство типа MainClass, то между классом будет двунаправленная связь; если OtherClass имеет неявное свойство типа MainClass (т. е. нет атрибута, но связь может быть получена путем работы в другом направлении), то будет иметь место однонаправленная ассоциация из MainClass в OtherClass.
В примерах 2, 3 и 4 MainClass не имеет свойств типа OtherClass. Однако он зависит от OtherClass, поэтому между MainClass и OtherClass могут существовать отношения зависимости. В коде это представлено использованием или #include.
Обычно я использую два разных соединителя в UML:
Когда класс зависит от реализации другого. Это будет означать, что класс создает или обрабатывает экземпляр другого. Таким образом, вызывающий класс зависит от класса реализации. Это было бы очевидно во всех ваших примерах.
Когда класс расширяет или реализует другой.