0% found this document useful (0 votes)
27 views

Module6 - Object Oriented Design - Design Principles

Uploaded by

GerardAlba
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
27 views

Module6 - Object Oriented Design - Design Principles

Uploaded by

GerardAlba
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 64

Module 6: Object-Oriented Design

Software Engineering
Computer Science
Academic Year 2023/2024

Gerard Albà Soler

1
Contents
1. Introduction
• What will we learn
2. Object Oriented Design
- Design principles
- Operation contract and Class diagram normalization
- Object responsibilities assignment
- Behavioral modeling. Sequence diagram and State diagram
- Design patterns
- Software Architecture
- Components and Packages
1. Introduction
What will we learn?

The requirements and object-oriented Analysis has focused on learning to do the right thing;
that is, understanding some of the goals for the case studies, and related rules and constraints.

By contrast, the following Design work will stress do the thing right;
that is, skillfully designing a solution to satisfy the requirements for this iteration.
1. Introduction
• Requirement Analysis
• The functionality users require from the system
• Use-case model
• OO Analysis (Static/Dynamic)
• Discovering classes and relationships
• Class diagram
• OO Design (Static/Dynamic)
• Result of Analysis expanded into technical solution
• Sequence diagram, state diagram, etc
• Results in detailed specifications for the coding phase
• Implementation (Programming/coding)
• Models are converted into code
• Testing
• Unit tests, integration tests, system tests and acceptance tests
1. Introduction
What will we learn?
• Design is the bridge between the analysis and implementation
of the software system.
• It is during design phase where we include technological
dependencies. Design phase is split in two distinct parts
software Design and software Architecture.

ü During this phase we assign responsibilities to the objects.


ü Normalize our diagrams and add additional information to them before implementation.
ü Apply design principles and design patterns to obtain a more flexible code.
ü Doing that, we are encouraging reusability (Classes, Components..).
• By this means, development and maintenance time are reduced and greater reliability and
efficiency is achieved (improved solutions).
1. Introduction
• When we are doing design, we can get more technical with the UML diagrams.
We can use more notation and be more precise. Some useful techniques are:

ü Class diagrams from a software perspective. These show the classes in the
software and how they interrelate
ü Sequence diagrams for common scenarios. A valuable approach is to pick the
most important and interesting scenarios from the use cases, or sequence
diagrams to figure out what happens in the software
ü Package diagrams to show the large-scale organization of the software
ü State diagrams for classes with complex life histories
ü Deployment diagrams to show the physical layout of the software
1. Introduction
What will we learn?
OOA/D

OO
Exercises
Design

OOA/D

Python Design
code Principles

GRASP
Contents
1. Introduction
• What will we learn
2. Object Oriented Design
- Design principles
- Operation contract and Class diagram normalization
- Object responsibilities assignment
- Behavioral modeling. Sequence diagram and State diagram
- Design patterns
- Software Architecture
- Components and Packages
2.1 Design Principles
• Set of guidelines that help to improve the overall design
• Techniques that have been used with success in many object-oriented designs
• By using them we avoid many common OO design mistakes resulting in rigid, fragile
and not reusable software
• The pillars for OOP are abstraction, encapsulation, inheritance and polymorphism,
as we’ve seen, but they are not enough to build high quality software
• On top of this concepts, we apply design principles
• Several names and techniques (GRASP, SOLID principles, Patterns also to design’s
problems, etc)
2.1 Design Principles
GRASP principles

• GRASP stands for: General Responsibility Assignment Software Pattern


• Set of 9 design principles that help us assigning responsibilities to classes
• We usually assign this responsibilities during the creation of diagrams
2.1 Design Principles
GRASP principles
• Responsibility: obligation to perform a task or knowing an information
• We can divide responsibilities in two types:
• Knowing responsibilities:
ü Get private and public object data
ü Get calculated or derived information
ü Get object references (knowing about other objects)
• Doing responsibilities:
ü Do something: create an object, process data...
ü Initiate and coordinate actions with other objects
2.1 Design Principles
GRASP patterns:
• Information Expert
• Creator
• Low coupling
• High cohesion
• Controller
• Indirection
• Polymorphism
• Pure Fabrication
• Protected Variations
2.1 Design Principles
Information Expert

Problem: What is a basic principle by which to assign responsibilities to objects?


Solution: Assign a responsibility to the class that has the information needed to fulfil it

• Given an operation that needs some input data to be performed, assign this
responsibility to the class that contains this data
2.1 Design Principles
Information expert

• Given the following diagram, assign the responsibilities to obtain the “sale order
total”, and the “total for all orders” for each customer
2.1 Design Principles
Information expert

• Assigning responsibilities requires collaboration between several partial information

• Each of the objects involved in the operation do their part, based on what they know

• All this responsibilities are assigned based on the information expert principle
2.1 Design Principles
Information Expert in Python
Example: In a payroll system, the Employee class should be responsible for calculating its salary,
as it has all the necessary information, such as base salary, hours worked, and bonuses.

• The Information Expert principle states that responsibilities should be assigned to the class
with the most knowledge or information required to fulfill the responsibility.
2.1 Design Principles
Information Expert

Example:
“Consider a scenario where you are designing a system for managing a library. When a user
wants to borrow a book, the responsibility of checking if the book is available should lie
with the Book class itself. The Book class contains information about its availability and can
perform the necessary checks without needing to rely on other classes. This promotes high
cohesion and reduces coupling between classes.”
2.1 Design Principles
Creator

Problem: Who creates object A?


Solution: Assign to class B the responsibility to create object A if one of these is true
(the more, the better):
ü B contains or compositely aggregates A
ü B closely uses A
ü B has the initialising data for A
ü B records A
2.1 Design Principles
• Creator is not only about having the data to create the object, but also being
closely related to it.

• Putting together two parts of code that are semantically close, the creation of an
object and the usage of it results in increased clarity, encapsulation and reusability

• A composite object is usually a good choice for creating its parts


2.1 Design Principles
Creator

• Who should be responsible of creating SaleOrder?


• Customer aggregates SaleOrder, it has the initialisation data and closely uses the
SaleOrder. It’s an ideal candidate for “Order Creator”
• May seem obvious but it’s worth to look at this when creating more complex
objects or arrays of objects
2.1 Design Principles
Creator

• We usually take this decisions while drawing sequence diagrams

• We add the creator operation inside Customer, and we do the same for the
SaleOrderLine creator, in this case, SaleOrder
2.1 Design Principles
Creator in Python
Example: In an e-commerce application, the Order class might be responsible fo
creating OrderItem objects, as it uses and aggregates these objects.

• The Creator principle involves assigning the responsibility of creating an object to a class
that uses the object, has the necessary information to create it, or aggregates the object.
2.1 Design Principles
Creator

Example:
Continuing with the library management system. In this system, when a new book is added
to the library, a Book object needs to be created. The responsibility for creating Book
objects should lie with a class like Library or a separate BookFactory class. This ensures that
the logic for creating Book objects is centralized and encapsulated, making it easier to
manage.
2.1 Design Principles
Low Coupling

Problem: How to reduce the impact of change? How to support low dependency and
increase reuse?
Solution: Assign responsibilities so that coupling remains low. Use this principle to
evaluate alternatives

* Coupling: interdependence between different parts of a software system. A high


coupling level means that changes in one module or component are likely to affect
other parts of the system, making it harder to modify and maintain
2.1 Design Principles
• The main goal is to assign dependencies that will reduce the impact of changes

• If we do not manage coupling we may end up with:

• No reusable design: classes have too many dependencies on others


• Maintainability problems: we change something that breaks everything
• High coupling = software difficult to read and understand
2.1 Design Principles
Low Coupling

• Types of coupling:

• A has an attribute type B


• A calls method B
• A has method that references B
• A is a direct or indirect subclass of B
• A implements the interface B
2.1 Design Principles
Low Coupling in Python
Example: Instead of having a direct dependency between the Order class and
the ShippingService class, we can introduce an interface, ShippingProvider, which reduces
coupling and allows for easier substitution of shipping services.

• Low Coupling involves minimizing dependencies between classes to reduce the impact of
changes and improve maintainability.
2.1 Design Principles
Low Coupling

Example:
In the library management system, suppose there is a LibraryCatalog class responsible for
managing the catalog of books. Instead of directly accessing the Book class to check
availability, the LibraryCatalog class can rely on an interface, such as Searchable,
implemented by Book. This way, LibraryCatalog remains loosely coupled with Book,
allowing for easier maintenance and changes.
2.1 Design Principles
High cohesion

Problem: How to keep objects focused, understandable, meanageable and as a side


effect, support Low Coupling?
Solution: Assign responsibilities so that cohesion remains high. Use this principle to
evaluate alternatives

* Cohesion: responsibilities and functions within a module are closely related and
serve a single purpose
2.1 Design Principles
• Focus classes around one responsibility

• High cohesive classes allow better mental abstraction as we can mentally label
them as “this class does X”, and not: “this class does A, B, C and a little bit of X
and Y”
2.1 Design Principles
High Cohesion in Python
Example: In a blogging platform, the Blog class should only be responsible for managing blog-
related activities, such as adding and removing posts, and not for handling user authentication.

• High Cohesion means grouping related responsibilities together within a single class to
make it easier to understand, maintain, and reuse.
2.1 Design Principles
High Cohesion

Example:

In the library management system, the Book class should have cohesive responsibilities
related to managing book details, such as title, author, and availability. Responsibilities
unrelated to book management, such as user authentication, should be handled by
separate classes. This ensures that each class is focused on a specific aspect of the system,
promoting clarity and maintainability.
2.1 Design Principles
Controller

Problem: What first object beyond the UI layer receives and coordinates a system
operation?

Solution: Assign the responsibility to an object representing one of these choices:

ü Represents the overall system or a major subsystem


ü Represents a use case scenario within the system operation occurs
2.1 Design Principles
• Basically, answer the question: “Who should be responsible of handling input
system events?

• An object controller is created in order to handle the system events. It’s the
first non-UI component that receives system operations as UI-events
2.1 Design Principles
Controller
• The controller has to:

üCapture the input event


üOrganise and coordinate the activity to react to this event
üInput events include everything that may interact with the UI (a person using the GUI,
signal from a sensor, call from an external system...)

• This responsibilities will be assigned to:

üOne single object for the overall system (Façade Controller)


üOne object for each use case, noted as: UseCaseName + Handler|Coordinator|Session
2.1 Design Principles
Controller in Python
• Example: In a web application,
a UserController class can handle user-related
events, such as registering and logging in,
delegating the actual processing to other classes.
• Assigns the responsibility of handling system
events to a dedicated class, which manages and
coordinates the system’s behavior.
• In this example, the UserController class acts as a
controller, responsible for handling user-related
events such as registering and logging in.
The UserService class contains the actual business
logic for registering and authenticating users.
2.1 Design Principles
Controller

Example:

In a web application for a library, when a user requests to borrow a book, the responsibility
of handling this request and coordinating the necessary actions should lie with a
BorrowBookController class. This controller class would interact with other classes, such as
Book, User, and Library, to facilitate the borrowing process. By centralizing control logic in a
controller class, the system becomes more organized and easier to manage.
2.1 Design Principles
Indirection

Problem: Where to assign a responsibility to avoid direct coupling between two or


more things?

Solution: Assign the responsibility to an intermediate object to mediate between


other components or services so they are not directly coupled
2.1 Design Principles
• Indirection pattern is used to reduce coupling between two classes A and B by
creating an intermediate class between them

• Like this, changes between A and B will not affect each other, the intermediate
class will absorb the changes

• Indirection supports low coupling but may reduce readability


2.1 Design Principles
Indirection
• Let’s avoid direct coupling between Customer and saleOrder:
2.1 Design Principles
Indirection in Python
• Example: In a notification system,
a NotificationService class can be
introduced to send notifications via
different channels, like email or SMS,
without directly coupling the sender
and receiver classes.

• Indirection introduces an
intermediate class or object to
mediate between other classes,
helping to maintain low coupling and
simplify interactions.
2.1 Design Principles
Indirection

Example:

In the library management system, if multiple classes need to access book information, an
BookRepository interface can be introduced. Classes that need access to book data can
depend on the BookRepository interface rather than directly on the Book class. This allows
for flexibility in how book information is retrieved, facilitating easier changes and
adaptations in the future.
2.1 Design Principles
Pure Fabrication

Problem: What object should have the responsibility, when you do not want to
violate High Cohesion and Low Coupling, but solutions offered by other principles
are not appropriate?

Solution: Assign a highly cohesive set of responsibilities to an artificial or


convenience class that does not represent a problem domain concept
2.1 Design Principles
• Sometimes there are responsibilities that doesn’t fit well any of our classes

• Forcing this responsibility to an existing cohesive class, it’s a bad idea

• Pure fabrication suggests to create a new class to achieve this new responsibility
2.1 Design Principles
Pure Fabrication in Python

• Example: In a file storage application,


the FileStorage class can be created to handle
file storage operations, separating it from the
core business logic
• Pure Fabrication involves creating an artificial
class to fulfill a specific responsibility when no
suitable class exists. This principle aims to
maintain high cohesion and low coupling by
avoiding the assignment of unrelated
responsibilities to existing classes
2.1 Design Principles
Pure Fabrication

Example:

Suppose the library management system needs to send email notifications to users when
they borrow or return books. Instead of adding email sending logic directly to the Book or
User classes, a separate NotificationService class can be created. This NotificationService
class acts as a pure fabrication responsible for sending email notifications, maintaining low
coupling and high cohesion in the system.
2.1 Design Principles
Protected Variations

Problem: How to design objects, subsystems and systems so that the variations or
instability in these elements does not have an undesirable impact on other
elements?

Solution: Identify points of predicted variation or instability, assign responsibilities


to create an interface around them
2.1 Design Principles
• We need to avoid changes in A that will affect B. So, we protect B from A
variations
• To achieve that, we organise responsibilities around well defined and organised
interfaces
• This principle is particularly relevant for the parts of the code that tends to
change often
• Introducing interfaces between this code and the rest of the system helps to
prevent problems
2.1 Design Principles
Protected Variations in Python

• Example: In a payment processing system,


the PaymentGateway interface protects the
system from changes in the implementations
of different payment methods, like
CreditCardPayment or PayPalPayment.
• Protected Variations involve encapsulating
variations and changes in the system behind
interfaces to minimize the impact of changes
and increase the system’s robustness. This
principle can be applied by using abstractions,
such as interfaces or abstract classes, to hide
implementation details.
2.1 Design Principles
Polymorphism

Problem: How handle alternatives based on type?

Solution: When related alternatives or behaviours vary by type (class), assign


responsibility for the behaviour (using polymorphism operations) to the types for
which the behaviour varies
2.1 Design Principles
• We can see polymorphism as having a base class with virtual methods that
defines an interface and derived classes that implements it

• We will use polymorphism when there are several ways to perform an action, and
we want to decouple this several ways to do it
2.1 Design Principles
Polymorphism

Example:
Continuing with the library management system, suppose there are different types of
books, such as FictionBook and NonFictionBook, each with its own borrowing rules. By
defining a common interface, Book, and implementing it in the FictionBook and
NonFictionBook classes, polymorphism allows the borrowing process to be handled
uniformly regardless of the book type. This promotes code reuse and simplifies the
handling of different book types within the system.
2.1 Design Principles
Principle Description
Information Expert Assign a responsibility to the class that has the information needed to fulfill it

Assign class B the responsibility to create an instance of class A if one of these is


true (the more the better):
• B ”contains” or compositely aggregates A.
Creator • B records A.
• B closely uses A.
• B has the initializing data for A that will be passed to A when it is created. Thus
B is an Expert with respect to creating A.
Assign the responsibility to a class representing one of the following choices:
Controller • Major subsystem classes.
• A use case scenario classes within which the system event occurs.

Low Coupling Assign a responsibility so that coupling remains low.


High Cohesion Assign a responsibility so that cohesion remains high.
2.1 Design Principles

Principle Description
Polymorphism The same name operations (methods) in the difference classes is defined. And
assign a responsibility to the class the class that the behavior is changed.

Pure Fabrication Define a class for convenience sake that doesn’t express the concept of the
problem area at all.

Indirection Assign the responsibility to an intermediate object to mediate between other


components or services, so that they are not directly coupled.

Protected Variations Assign responsibility to create a stable interface around an unstable or predictably
variable subsystem or component.
2.1 Design Principles
References
• You can learn more about GRASP (with Python examples) here:

https://youtu.be/fGNF6wuD-fg?si=hu9m91cccbuRw9XB
2.1 Design Principles
Activity 6.1.1
Which one of the following principles has been applied to code the Customer class:

A: Protected Variations
B: Controller
C: Creator
D: Low Coupling
2.1 Design Principles
Activity 6.1.2
Consider a scenario where a
PaymentProcessor class interacts
with a PaymentGateway class, as
follows. Which design principle
are we applying?

A: Information Expert
B: High Cohesion
C: Creator
D: Low Coupling
2.1 Design Principles
Activity 6.1.3
Let’s consider a Shape interface
can be implemented by various
geometric shape classes such as
Circle, Square, and Triangle.
Which design principle are we
applying in the code on the right:

A: Information Expert
B: High Cohesion
C: Polymorphism
D: Low Coupling
2.1 Design Principles
Activity 6.1.4
In a web application, a UserController class could handle user registration, login, and profile
update functionalities like in the code below:
Which one of the following principles has been applied to code the UserController class:

A: Protected Variations
B: Controller
C: Creator
D: Low Coupling
2.1 Design Principles
Activity 6.1.5
Creating a FileParser class responsible for parsing specific file formats for our problem, can be
considered a ____?____ , as it does not really represent a domain concept, and it is specially
designed to handle complex operations

A: Low Coupling
B: Information Expert
C: High Cohesion
D: Pure Fabrication
2.1 Design Principles
Activity 6.1.6
Which one of the following principles has been applied to code the Order class:

A: Low Coupling
B: Information Expert
C: High Cohesion
D: Pure Fabrication
2.1 Design Principles
Activity 6.1.7

Consider a scenario where we have a DataStore class that provides access to a database. To
protect against changes in the database technology or schema, we can encapsulate the
database-specific logic within the DataStore class.
Which one of the following principles are we using when creating such class:

A: Creator
B: Information Expert
C: Protected Variations
D: Pure Fabrication
2.1 Design Principles
Activity 6.1.8
In the following example of code, a Logger class can act as an intermediary between multiple
classes, allowing them to log messages without directly coupling to a specific logging
implementation:
Which one of the following designs has been applied?

A: Indirection
B: Protected Variations
C: High Cohesion
D: Creator
2.1 Design Principles
Activity 6.1.9
Let’s consider a Car class should have methods for starting the engine, accelerating, braking,
and turning, rather than mixing unrelated functionalities
Which one of the following designs has been applied?

A: Indirection
B: Protected Variations
C: High Cohesion
D: Creator

You might also like