Shortcut to seniority
Home
Go to main page
Section level: Junior
A journey into the programming realm
Section level: Intermediate
The point of no return
Section level: Senior
Leaping into the unknown
                    Go to main page
A journey into the programming realm
The point of no return
Leaping into the unknown
It is very important to be able to represent our system visually, especially when it’s a complex one. Using a common language such as UML diagrams allows teams to collaborate for the quality of the project.
Modelling is a way to visualize the design of the application, and compare it against requirements before we start the actual coding. With UML diagrams, you can visualize and validate the architecture of the software before implementing it.
The Unified Modeling Language (UML) is a modeling language for designing systems. UML establishes a standard semantic and syntactic structure, that developers can use to model almost any type of application, regardless of the hardware, Operating System, or programming language.
Using diagrams to “read” the code provide a number of benefits, such as:
There are two types of diagrams:
Class diagrams show the structure of a system as classes and their relation with other classes within the system.
                                            Composition is a strong association.
                                        The life of the contained object totally depends on the container object.
Aggregation is a weak association.
                                        The life of the contained object does not depend on the container object.
Inheritance occurs when one class inherits all the non-private properties (methods/variables) that the base class provides, in order to maximize the code reuse and reduce code duplication.
Based on the visibility level, the attributes and methods receive a sign, such as:
The diagram has been drawn by using the following code:
                                            
                                                title Class Diagram 
                                                class BaseClass { 
                                                    .. public access .. 
                                                    +void public_method() 
                                                    +int public_variable 
                                                    .. protected access .. 
                                                    #void protected_method() 
                                                    #int protected_variable 
                                                    .. private access .. 
                                                    -void private_method() 
                                                    -int private_variable 
                                                    .. 
                                                    {abstract} void abstract_method() 
                                                    {static} int static_method() 
                                                } 
                                                BaseClass <|-- DerivedClass : inherits 
                                                BaseClass *-- CompositionClass : composition 
                                                BaseClass o-- AggregationClass : aggregation
                                            
                                        
                                        
                                            The title is what’s visible on top of the image. 
                                            Afterwards, we define a class and a few methods and variables. 
                                            These variables are separated in public, protected, and private access, so the diagram will draw a line above them, and display specific icons based on their current access level.
 
                                            This is helpful as it's a fast way for everyone to know what variables are available and how we can access them. 
                                            Below the class, we have various ways of linking the classes, which changes how they are rendered.
                                        
Component diagrams show components and the dependencies between them.
                                            A high-level view of a component is modeled with a rectangle, and can contain the component name, an icon, or text and icon.
Interfaces are of two types, provided and required.
Provided interfaces are those exposed by our component (We are the server side that receive requests from the clients and work on those requests, and notify the clients when something changes).
Required interfaces are those exposed by internal or external components to which we connect upon. (We are the client side that receive updates from the server and request information from it).
The diagram has been drawn by using the following code:
                                            
                                                title Component Diagram 
                                                interface "External interface" as Ext 
                                                package "Package level" { 
                                                    [Component Intern Server] -up-> InternalInterface : provides 
                                                    [Component Intern Client] ..> InternalInterface : uses 
                                                } 
                                                [Component Intern Client] ..> Ext : uses 
                                                Ext - [Ext Component Server] : provides
                                            
                                        
                                        
                                            The title is what’s visible on top of the image.
                                            Afterwards, we define an interface of some name and provide an alias for it.
                                            At the package level, one component provides an interface, while another one uses it.
                                            The internal component we previously defined will also connect to an external interface. Up to now, we do not know who will be the provider of this interface.
                                            We then define another component which provides the interface as external (the one we created and aliased before).
                                        
State machine diagrams show the states and state transitions of a system. The purpose of a state diagram is to display changes in the class state.
                                            Initial state is drawn with a black filled circle, and represents the initial state of the system.
States are drawn as rectangles, and they are used to represent the state.Transitions are drawn as a solid arrow, representing the transition from one state to another.
At the top of the arrow, we write the event which caused the state change, and optionally, a method to call when the event is fired.
A self-transition is drawn as an arrow pointing back to the same state. We usually call an action when an event changes / triggers and we don’t want to change the state.
Final state is drawn with a black filled circle within a circle, and represents the final state of the system.
                                            
                                                title State Diagram 
                                                [*] --> Startup Startup --> InitializingState : onEventInit 
                                                Startup --> Startup : onEventRetryInit / onInitAction() 
                                                InitializingState -right-> IdleState : StartupSuccess 
                                                InitializingState -right-> ErrorState : StartupFailed 
                                                ErrorState --> IdleState : StartupSuccess 
                                                IdleState --> ErrorState : OnError
                                                IdleState --> [*] : onEventShutdown 
                                                ErrorState --> [*] : onEventShutdown 
                                                IdleState : --> onEntryAction 
                                                IdleState : <-- onExitAction
                                            
                                        
                                    Sequence diagrams show how objects communicate with each other and the sequence of their messages.
                                            Participants describe the way an object behaves. They are represented with a rectangle shape.
Messages are drawn as arrows that represent communication between objects. Filled arrows are used for synchronous messages, whereas half-arrowed lines are used to represent asynchronous messages.
A reply message is drawn with a dotted line and an open arrow.
Reflexive messages occur when an object sends a message to itself.
It is drawn as a message arrow that starts and ends at the same lifeline.
The alt (alternative) label refers to an if-else statement:
There’s no possibility of both messages to be sent.
                                            
                                                title Sequence Diagram 
                                                participant Message_Sender 
                                                participant Message_Receiver 
                                                Message_Sender -> Message_Receiver : Synchronous request message 
                                                Message_Sender <- Message_Receiver : Synchronous reply message 
                                                Message_Sender --> Message_Receiver : Asynchronous request message 
                                                activate Message_Receiver 
                                                Message_Receiver -> Message_Receiver : Reflexive message 
                                                return done 
                                                ||50|| 
                                                Message_Sender -> Message_Receiver : Some Important Message 
                                                alt on success 
                                                Message_Sender <- Message_Receiver : Success Message 
                                                else on failure 
                                                Message_Sender <- Message_Receiver : Failure Message 
                                                end
                                            
                                        
                                    Data race occurs when more than two threads access the same memory and one of them is a write.
Polymorphism – “poly” (many) + “morphe” (form)
Binary search: split the range in half and check it from there. Based on the result, you will reduce half of the work by knowing in which half is the problem contained.