Design patterns with examples on the UML class diagram

Lecture



Basic patterns

  • Mapper (Distributor)
  • Money
  • Special Case (Special Case)
  • Plugin
  • Gateway
  • Separated Interface (Dedicated Interface)
  • Registry (Registry)
  • Service Stub ( Service Stub )
  • Value Object ( Value Object )
  • Record Set ()
  • Layer Supertype (Supertype Level)
  • Singleton

Web View Patterns

  • Transform View (Transducer)
  • Template View
  • Application Controller ( Application Controller )
  • Two Step View (two-step templating)
  • Page Controller ( Page Controller )
  • Front Controller (Entry Controller / Single Entry Point)
  • MVC - Model View Controller (Model-View-Controller)

Patterns of data source architecture

  • Row Data Gateway (Gateway to Record Data )
  • Active Record
  • Table Data Gateway (Gateway to Table Data )
  • Data Mapper ()

Object-Relational Logic Patterns

  • Lazy Load (Lazy loading)
  • Identity Map (Presence / Compliance Map)
  • Unit of Work

Object-Relational Patterning Patterns

  • Identity Field (Primary Key Field)
  • Foreign Key Mapping ( Foreign Key Mapping )
  • Association Table Mapping
  • Dependent Mapping (Management of distribution of subordinate entities)
  • Embedded Value (Combined Property)
  • Serialized LOB (Serialized LOB)
  • Single Table Inheritance (Inheritance with a single table)
  • Class Table Inheritance (Inheritance with class tables)
  • Concrete Table Inheritance (Inheritance with tables of finite classes)
  • Inherritance Mappers (Inherited Distributors)

Entity Logic Patterns

  • Transaction Script ( Transaction Script )
  • Domain Model
  • Table Module
  • Service Layer (Service Level)

Object-Relational Metadata Processing Patterns

  • Metadata Mapping (Distribution Based on Metadata)
  • Query Object ( Query Object )
  • Repository

Data distribution patterns

  • Remote Facade (Front Entrance)
  • Data Transfer Object

Patterns of local competition

  • Optimistic Offline Lock (Optimistic Lock)
  • Pessimistic Offline Lock (Pessimistic Lock)
  • Coarse Grained Lock (Rough Lock)
  • Implicit Lock (Hidden lock)

Legend

Class symbol in UML class diagram

The class symbol in a chart may look differently depending on the chart’s details:
  Design patterns with examples on the UML class diagram

Issues of detail will be discussed in the following sections, and now we need to note that the class symbol contains the name (Player), the set of operations (move, get_gealth) and attributes (pos, state). For class elements, the type, multiplicity, visibility, etc can be specified:

Attribute specification format:
visibility name: type [multiplicity] = default_value

Operation specification format:
visibility name (argument: type) = return_type

Depending on the visibility parameter, the element may be:

  • private ( private , available only inside the class) - specified by the minus symbol (-), can be displayed as a square;
  • protected ( protected , available inside the class, as well as within the heir classes) - specified by the "pound" symbol (#), can be displayed as a rhombus;
  • open ( public , accessible to all) - set by the symbol “plus” (+), can be displayed as a circle.

The virtual function and the name of the abstract class are in italics, and the static function is underlined.

Types of patterns

  •   Design patterns with examples on the UML class diagram - behavioral (behavioral);
  •   Design patterns with examples on the UML class diagram - generators (creational);
  •   Design patterns with examples on the UML class diagram - structural (structural).

1.2 Class Relationships on a UML Diagram

Symbols of relations between classes

  •   Design patterns with examples on the UML class diagram - aggregation - describes the relationship "part" - "whole", in which the "part" can exist separately from the "whole". The diamond is indicated by the "whole".
  •   Design patterns with examples on the UML class diagram - composition (composition) - a subspecies of aggregation in which "parts" cannot exist separately from the "whole".
  •   Design patterns with examples on the UML class diagram - dependence (dependency) - a change in one entity (independent) may affect the state or behavior of another entity (dependent). From the direction of the arrow indicates an independent entity.
  •   Design patterns with examples on the UML class diagram - generalization (generalization) - the ratio of inheritance or implementation of the interface. From the direction of the arrow is a superclass or interface.

The class diagram allows different kinds of relationships, consider them on the part of the diagram of the model of a game:
  Design patterns with examples on the UML class diagram

The game has different types of elements (walls, chests, characters). All these elements are descendants of the AbstractItem abstract class, with some of them able to move (such elements must be inherited from MovingItem). Inheritance (the “is” relationship) is depicted using a solid line with a closed arrow pointing towards the superclass - in the diagram, the MovingItem class inherits from AbstractItem, the Player class from MovingItem, etc. The dashed line with the closed arrow sets the relation of realization (closed inheritance).

Another type of relationship between classes is inclusion; in object-oriented programming, there are two types of this relationship — composition and aggregation. Recall that composition is a kind of inclusion, when objects are inextricably linked to each other (their lifetime coincides), in the case of aggregation, the lifetime is different (for example, when an object of a nested class can be replaced by another object during program execution).

The composition relation is indicated by a filled in rhombus, which is drawn from the side of the enclosing class — for example, the MovingItem class includes the Position class, since a moving object always has a position. The aggregation relation is represented by an empty diamond - the player (Player) aggregates the state (IPlayerState).

If you are familiar with the State, Strategy or Delegation patterns, you can skip the section.
The diagram above uses the State design pattern (a State), which is a type of Delegation pattern and is close to the Strategy pattern. The essence of delegation lies in the fact that in order to simplify the logic of the class, a part of its work can be transferred (delegated) to the auxiliary class. In turn, the State pattern can be added, for example, at the stage of refactoring, if in several class functions there is a razlapistya check of the state of an object to perform certain actions. In our case, the character can interact with the hedgehog, suppose that if the character moves sitting and contacts the hedgehog, his health should decrease, and if he stands, the score (points) will increase. In addition to the hedgehog, there could be food, opponents, ammunition, etc. To demonstrate this pattern, the abstract class IPlayerState and two heirs StayState and SeatState are created. In the Player class, when you press the Ctrl button, the state could change to SeatState, and when released, to StayState. Thus, when executing state-> process_hedgehog ( this ), our player in some way, defined by the state object, contacts the hedgehog.

The Delegation design pattern (and all its variants) is a good example for demonstrating aggregation. In our case, the player’s state may change due to the change of the object according to the pointer, i.e. the lifetime of objects varies.

The most common type of relationship between classes is an association, indicated by a solid line (sometimes with an arrow). In general, both composition, and aggregation, and generalization (inheritance) are special cases of association. In our diagram, using association, it is shown that the IPlayerState class changes the stats (health and points) of the Player object. The association may have a name of the relationship explaining the essence of the relationship. The name of the corresponding variable is often used as the name of the relations of composition and aggregation. In addition, the association can have multiplicity, it is set at the ends of the line:

  • 1 - one connection (our diagram shows that one player includes one instance of the IPlayerState class);
  • * any number of links (if the diagram had a class of the playing field, then using an asterisk it would be possible to show that it can contain an arbitrary number of game elements);
  • [from .. to] - can be set by range. So the range [0 .. *] is equivalent to an asterisk, but if we want to show that there should be more than one object, we can write down [1 .. *]

The last kind of relationship, which we consider - dependence, is represented by a dashed (dashed) line. If there is an arrow, then it is directed from the dependent to the independent class, if the arrow is not present, then the classes depend on each other. Dependence is an interface dependence, i.e. if the interface of an independent class changes, then you have to make changes to the dependent class. In our diagram, SeatState and StayState depend on the Player class, since refer to his methods for changing player characteristics. To depict the friendship between classes, the dependency relationship with the signature friend is used .

Obviously, not all types of relationships should be displayed on the diagram and one relationship can be replaced by another. So, I would remove the dependency relationship from our example, but under certain circumstances (for example, when sketching on a whiteboard) they would be quite appropriate. The arrangement of multiplicities and names of links is also not performed in all cases. In general, do not put extra information on the chart. The main thing is that the diagram should be visual.

A list of design patterns using the UML class diagram

  Design patterns with examples on the UML class diagram

Keeper (memento)

  Design patterns with examples on the UML class diagram

Chain of responsibility

  Design patterns with examples on the UML class diagram

Observer

  Design patterns with examples on the UML class diagram

Command (command)

  Design patterns with examples on the UML class diagram

State

  Design patterns with examples on the UML class diagram

Interpreter

  Design patterns with examples on the UML class diagram

Strategy

  Design patterns with examples on the UML class diagram

Iterator

  Design patterns with examples on the UML class diagram

Template Method

  Design patterns with examples on the UML class diagram

Mediator

  Design patterns with examples on the UML class diagram

Visitor

  Design patterns with examples on the UML class diagram

Adapter

  Design patterns with examples on the UML class diagram

Proxy (proxy)

  Design patterns with examples on the UML class diagram

Bridge

  Design patterns with examples on the UML class diagram

Abstract factory

  Design patterns with examples on the UML class diagram

Linker (composite)

  Design patterns with examples on the UML class diagram

Builder

  Design patterns with examples on the UML class diagram

Decorator

  Design patterns with examples on the UML class diagram

Factory method

  Design patterns with examples on the UML class diagram

Facade

  Design patterns with examples on the UML class diagram

Prototype

  Design patterns with examples on the UML class diagram

Flyweight

  Design patterns with examples on the UML class diagram

Singleton

  Design patterns with examples on the UML class diagram

2 Using the class diagram

We considered the basic notation used in class diagrams - they should be sufficient in most cases. At least, owning this material you can easily understand the diagrams of design patterns and understand the sketch of any project. However, how to build such diagrams correctly? In what order and with what degree of detail? - The answer depends on the purpose of the chart, so the material will be divided into subsections in accordance with the objectives of the simulation.

It is worth noting that Gradi Buch has tips on using UML in the book “User Guide” [Buch_Rambo], but in his “Object Oriented Analysis” [Buch] you can find good examples and project quality criteria. Leonenkov [Leonenkov] avoids this topic altogether, leaving only references to literature, I found specific recommendations from Larman [Larman] and Rosenberg [Rosenberg], part of the material is based on my personal experience. Fowler views UML as a means of sketching, so he has his own (very different from Butch and Rosenberg) view of the [Fauler] class diagram.

2.1 Class diagram as a system dictionary, conceptual model

The system dictionary is formed in parallel with the development of a use case diagram, i.e. technical specifications. It looks like this - you ask the customer questions like “what else can the user do?”, “What will happen (should the system issue) if the user does click on button?”, And write down the answers to them in the form of a description of precedents. However, the customer, giving answers, can call the same things with different names - from personal experience: by saying “cell”, “intersection”, “node” and “cell”, the customer can mean the same thing. In your system, all these concepts should be represented by one abstraction (class / function / ...). To do this, when communicating with the customer, it is worthwhile to fix the terminology in the form of a system dictionary - the class diagram copes with this very well.

Grady Buch to build a dictionary of the system offers to perform in the following order [BuchRambo]:

  1. analyzing the use cases, determine which elements users and developers use to describe the task or its solution;
  2. identify for each abstraction corresponding to its many responsibilities (responsibility). Track the correctness of the distribution of duties (including, adherence to the principle of a single duty [solid_refactoring]);
  3. develop procedures and operations for the classes to perform their duties.

As an example, consider the dictionary system for the game "Minesweeper". The diagram below shows the variation that resulted from my student’s discussion of the problem. It can be seen that the diagram shows the entities and their attributes that are understandable for the customer; this diagram should be seen before drawing up precedents so as not to call the “Cell” - “Field”, misleading everyone. When constructing a system vocabulary, you should avoid drawing class functions on a diagram, since this detailed assignment of responsibilities is best performed after the construction of interaction diagrams.

  Design patterns with examples on the UML class diagram

In the design process, the vocabulary of the system can be supplemented, Rosenberg demonstrates this very well in his book describing the iterative ICONIX design process [Rosenberg]. For example, after reviewing several cases, it may turn out that several classes implement the same functionality — to solve a problem, it is necessary to spell out the responsibilities of each class more clearly, perhaps add a new class and transfer some of these responsibilities to it.

Larman proposes to build a conceptual model of the system [Larman] - this is approximately what we described as a system dictionary, but in addition to the terms of the subject area, it records some relationships that are understandable to the customer. For example, the customer understands (and fixes in the technical task) that is made up by - therefore, there is a relationship between the seller and purchase "makes out". I recommend building a conceptual model, modifying the system’s vocabulary, although Larman recommends adding associations first, and then adding attributes.

2.2 Design Level Classes Diagram

In any object-oriented design process, the class diagram is the result, because is the model closest to the implementation (code). There are tools that can convert a class diagram into code — this process is called code generation and is supported by many IDE and design tools. For example, Visual Paradigm performs code generation (available as plugins for many IDEs), new versions of Microsoft Visual Studio, UML modeling tools such as StarUML, ArgoUML, etc. To build good code using a diagram, it must be sufficiently detailed. It is about such a chart in this section.

Before Larman [Larman], before the construction of a design level class diagram begins, interaction diagrams and a conceptual model of the system should be constructed. The order of construction of the diagram is as follows:

  1. transfer classes from a sequence diagram;
  2. add attributes of the conceptual model;
  3. добавить имена методов по анализу диаграмм взаимодействия (например, диаграмм последовательностей [uml_sequence_diag]);
  4. добавить типы атрибутов и методов;
  5. добавить ассоциации (на основании атрибутов — отношения композиции и агрегации);
  6. добавить стрелки (направление ассоциаций)
  7. добавить ассоциации, определяющие другие виды отношений (в первую очередь, наследование).

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

Например, при анализе задания на игру «Сапер» мы выделили классы <Флажок> и <Мина>, но будут ли эти классы в окончательном проекте или останутся только в воображении? — решение можно принять только проанализировав диаграммы взаимодействия. Ведь возможен и такой код:

  1. enum class CellType {
  2. EmptyOpened, EmptyClose, EmptyCloseFlagged,
  3. MineOpened, MineClose, MineCloseFlagged
  4. };
  5. class PlayingGround {
  6. // ...
  7. CellType **m_ground;
  8. }

Поясню (для тех, кто не пишет на С++) — тут создается перечисление, которое задает тип ячейки. Ячейка может принимать одно из этих шести значений (пустая открытая, пустая закрытая, пустая закрытая с флажком и т.п.). В таком случае, ячейка никак не сможет сама реагировать на нажатия мыши и отвечать за свое отображение (например пустая открытаядолжна выводить число мин вокруг себя) — все эти обязанности, видимо, лягут на класс PlayingGround.

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

2.3 Диаграмма классов для эскизирования, документирования

Под эскизированием понимают моделирование некоторой (интересной нам в данный момент) части системы. Например, эскизирование может выполняться на маркерной доске когда в вашу компанию попадет новый сотрудник и вы будете помогать ему «влиться» в существующий проект. Очевидно, что если если дать человеку диаграмму классов уровня проектирования — разбираться он будет долго. Суть эскизирования в избирательности — вы выносите на диаграмму только те элементы, которые важны для пояснения того или иного механизма.

Сторонником применения UML для эскизирования является Фаулер [Fauler], который считает, что целостный процесс проектирования с использованием UML слишком сложен. Эскизирование применяется очень часто (не только при объяснении проекта на маркерной доске):

  • в любой книге, посвященной паттернам проектирования, вы найдете массу UML диаграмм, выполненных в этом стиле;
  • при моделировании прецедента выбираются классы, за счет которых этот прецедент реализуется. Моделирование прецедента выполняется при рефакторинге;
  • в документацию для разработчиков нет смысла вставлять диаграмму классов уровня проектирования — гораздо полезнее описать наиболее важные (ключевые) моменты системы. Для этого строятся эскизные диаграммы классов и диаграммы взаимодействия. Также существуют специальные инструменты построения документацию по готовому коду — такие как JavaDoc или Doxygen[doxygen_codegeneration], в частности они строят диаграмму классов, но чтобы документация была понятной, в исходный код программы требуется вносить комментарии специального вида.

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

3.4 Диаграмма классов для моделирования БД

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

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

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

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

Для моделирования схемы БД с помощью диаграммы классов нужно [Buch_Rambo]:

  1. идентифицировать классы, данные которых должны храниться между запусками приложения (или обращениями пользователя) и нанести эти классы на отдельную диаграмму;
  2. детально специфицировать атрибуты классов, ассоциации и кратности. В ER модели кратности имеют огромное значение — так например, при наличии кратности «многие-ко-многим» придется создавать вспомогательную таблицу. Используйте специфические стереотипы классов и пометки атрибутов (для задания первичных и вторичных ключей, например) [uml_datamodeling];
  3. решить проблемы использования полученной диаграммы в качестве физической модели базы данных — циклические ассоциации, n-арные ассоциации и т.д. При необходимости создать промежуточные абстракции;
  4. раскрыть операции, важные для доступа к данным и поддержания целостности;

Comments


To leave a comment
If you have any suggestion, idea, thanks or comment, feel free to write. We really value feedback and are glad to hear your opinion.
To reply

Web site or software design

Terms: Web site or software design