-
Notifications
You must be signed in to change notification settings - Fork 14
Basic requirements
The main goal of this section is to provide the required knowledge for understanding the following sections and help you to take advantage of this documentation. Maybe you already know all the subject here, in this case, do NOT skip this section, just take a fast look.
Since I started my studies in software engineering, I noticed that many people know how to create class diagram, but just a few people really understand how to translate it real code (I had this same problem). One day I found a book called "PHP: Programming with Oriented Object" written by Pablo Dall`Oglio. In the chapter two of this book, the author made a great revision about PHP with UML, and he explained each element of class diagram and the meaning of those elements in the code.
I will NOT focus on the obvious element of a class diagram, I will focus only on three of them: association, composition, and aggregation. I have chosen those elements, because people constantly misunderstood these concepts. Finally, it is important to correctly comprehend of those elements.
The figure above shows the association between two classes. Look to the attribute "provider" in class Product, basically, it keeps the reference in the memory where we can find another object which we can use their methods and attributes. When we think in code, the common way to implement an association it is by having one object as attribute of the others. The code below shows the implementation of the association:
class Provider
attr_accessor :id
attr_accessor :name
attr_accessor :type
attr_accessor :address
end
class Product
attr_accessor :id
attr_accessor :name
attr_accessor :provider
end
The idea behind of aggregation consisting of make an external object as part of itself. It means that parent objects can use the functionalities of the aggregation objects. In the aggregation, the object can have a lot of objects of another class by using an array.
The Basket can have any kind of products, hence, we need to create one method for "aggregate" the products to the basket. The other methods in basket, use product object added. See the code below with the implementation.
class Product
attr_accessor :code
attr_accessor :description
attr_accessor :price
attr_accessor :provider
end
class Basket
@items
def add_item(pProduct)
@items.append(pProduct)
end
def show_items
@items.each_with_index do |item, i|
puts "Item #{i + 1}: #{item.description}"
end
end
def calculate_total
total = 0
@item.each do |item|
total = item.price + total
end
return total
end
end
Notice that "basket" never creates an object of "Product", it just uses it. Likewise, if the basket is destroyed, all objects still will remain in the memory.
Composition, the parent object really has a child object in the memory, in other words, the parent is responsible for creating an object and use it to compose itself. If the parent object is destroyed, the "compound" objects will be destroyed together.
See the code below with:
class Contact
@name
@telephone
@email
def set_contact(pName, pTelephone, pEmail)
@name = pName
@telephone = pTelephone
@email = pEmail
end
end
class Provider
@code
@socialReason
@address
@city
@contact
def initialize
@contact = Contact.new
end
def set_contact(name, telephone, email)
@contact.set_contact(name, telephone, email)
end
end
Notice in the code above, that "Provider" is responsible for creating an instance of "Contact".
Kuniri uses a set of design patterns, before we introduce our architecture, we believe that's a good idea for introducing the basics concepts behind the patterns applied by this project. Basically, we will show here three main patterns used in the project: State, Template Method, and Strategy. All the explanations used here, are based on the book "Design Pattern, Element of Reusable Object-Oriented Software - GoF".
"This pattern allows an object to change its behaviour when its internal state changes. The object will appear to change its class.". This pattern encapsulates the states on a separate class, and delegating tasks to the objects that represents the current state (we know the behaviour changes with the internal state). If an object used by you can totally change their behaviour, you will feel like the new instances was created based on other classes. Actually, we use the composition to create the idea of change class by the reference of many different objects.
The class diagram above, illustrates the structure of state pattern. The class Context, defines the interface of interest to clients, and maintains an instance of a ConcreteState subclass that defines the current state.
The State class, defines an interface for encapsulating the behaviour associated with a particular state of the Context. Finally, ConcreteState subclasses implement a behaviour associated with a state of the Context.
Define the skeleton of an algorithm in an operation, postpone some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure. Basically, this pattern are based on the creation of template for one algorithm. Those templates are simple, or more deeply, it is one method which define one algorithm like a sequence of steps. One or more of those steps can be defined as abstract and implemented by a subclass. This ensures that the algorithm structure still unchanged, even the subclasses provide parts of the implementation.
The figure above illustrates the overview of template pattern. The AbstractClass, defines primitive operations, which concrete subclasses define to implement steps of an algorithm. Implements a template method defining the skeleton of an algorithm. The template method calls primitive operations as well as operations defined in AbstracClass or those of other objects. Finally, ConcreteClass implements the primitive operations to carry out subclass-specific steps of the algorithm.