Professional Documents
Culture Documents
Schermafbeelding 2024-04-26 Om 23.11.41
Schermafbeelding 2024-04-26 Om 23.11.41
Summary
Utrecht University, Informatiekunde
2020-2021, blok 1
Lecturer: Arjan Eggens
Summary: Ayco Geul
Table of Contents
1 Programming tools: functions, modules and classes. 3
1.1 Functions 3
1.2 Module 3
1.3 Class 3
1.4 Class inheritance 4
1.5 Type hints 5
1
5.1 From Requirements to Design 16
5.2 Cohesion and coupling 17
5.3 Responsibility 17
5.4 GRASP Principles 18
6 UML 19
6.1 Analysis 19
6.2 UML diagrams 19
6.2.1: Activity diagrams 19
6.2.2: UML: Class Diagram 20
Associations 22
6.2.3 UML: Sequence diagrams 22
7 Design Patterns 23
Upfront Design 23
Principles for a good design 24
7.1 The Facade Pattern 26
7.2 The Adapter Pattern 27
7.3 The Strategy Pattern 28
7.4 The Bridge Pattern 29
7.5 The Abstract Factory 30
7.6 The Decorator Pattern 30
8 Design By Contract 32
Hoare Logic 32
Design by Contracts 33
10 OO Principles 40
2
1 Programming tools: functions, modules and
classes.
1.1 Functions
Translates into a complex expression.
Example:
A function:
- Groups related code
- Provides generic interface via parameters
- returns values
1.2 Module
A module:
- Groups functions and constants (that are useful in other parts of an application)
1.3 Class
A class:
- Groups functions
- contains data
3
1.4 Class inheritance
Allows you to indicate that certain types are related and should behave the same
For example: a class rectangle and circle are both shapes where you can compute the area
from.
The Shape class should act purely as an interface/contract how shaped are implemented.
Shape itself is an abstract class and should not be used to generate shapes.
4
2 Waterfall & (R)UP
What is a way to create a good fundament for complex software?
One of the first widely used development processes is the Waterfall model
The waterfall model doesn’t deal well with change.Its a one way path. New models
emerged.
● (Rational) Unified Process / RUP
● Extreme Programming
● Scrum
● Kanban
● Do whatever
5
○ Develop software in time-box mini-projects called iterations
○ Iterations are stand alone projects with its own milestones etc.
● Embrace change
○ Stakeholders change their mind/requirements all the time.
○ Iterations make those changes possible.
6
2.2.3 Different activities of UP
During those 4 phases of UP, multiple activities are done. There are engineering activities
and supporting activities.
Engineering activities in UP
1. Business modelling
a. Establish a common understanding between stakeholders about how the
organization works.
2. Requirements engineering
a. Describes what the system should do
3. Analysis and Design
a. How the system should be implemented.
4. Implementation
5. Test
6. Deployment
Supporting activities in UP
1. Project management work
2. Configuration and change Management
3. Environment: development kit, tools for building and process control
7
3 Agile development processes
Mainly talk about Scrum today
Agile is a collection of processes (not just a process)
8
3.3 The Scrum Process
Sprints
● Each iteration of SCRUM is called a Sprint.
● Length is about 2-4 weeks.
● This scope can’t be changed during the Sprint.
● Parts of a sprint
1. Sprint planning (Result: Sprint backlog)
a. What items will be worked on during the sprint
b. Tasks needed to deliver these items
2. Daily Scrum / Daily stand up (Short meeting +- 15 minutes
a. Discuss practical issues to make sure there are no bottlenecks.
3. Sprint review - Results are discussed with stakeholders
a. Provides feedback
b. Show the output of the sprint
c. Consider the effect on the planning on the next sprint
9
4. Sprint retrospective - Deals with the process (Did we follow the process
correctly?)
a. Goal: Always improve and finetune the process.
Scrum Artifacts
1. Product Backlog
Ordered list of all the possible changes that could be made to the product.
2. Sprint Backlog
a. Collection of items from the product backlog that's created at the beginning of
each sprint.
b. Contains specific tasks which needs to be done to deliver those items.
3. Definition of Done
Explains the criteria that a Product Backlog Item must fulfill to be considered done.
4. Increment
Collection of items that passed the Definition of Done at the end of the sprint.
Scrum Roles
Product Owner
- Manage the Product Backlog.
- Uses the Product Backlog to give the development team direction to where the
software product is headed.
Scrum Master
- Ensures that the development process stays Agile.
- Coaching role
Development Team
- Perform tasks in the Sprint Backlogs
- Decides how to divide the tasks
10
4 Requirements Engineering (Development
process)
Why is it useful?
By knowing what the requirements are, communication and planning can be done correctly.
● Software errors can be very costly (NASA project costed $60 billion dollars/yr)
● 3 out of 4 software projects are unsuccessful
○ Due to poor planning and communication.
Definitions
Requirements:
- a feature that the system must have, or
- a constraint it must satisfy
Requirements are required and not just a wish list. Make sure you can promise to deliver.
Requirements engineering:
- The process of identifying and defining all the requirements of a software system.
- It is a cycling process of 4 steps:
1. Elicitation
2. Specification (e.g. use cases/scenarios)
3. Validation and verification
4. Negotiation
11
Examples of requirements
1. Functional: actual features of a system
2. Usability (online help)
3. Reliability (uptime, recoverability)
4. Performance (how long it takes to respond)
5. Supportability (easily updatable)
Other sub-factors:
6. Implementation (which languages, tools, hardware)
7. Legal (licensing)
8. Interface (e.g. assignment submission system must be paired with Osiris)
4.1 Elicitation
Elicitation can be harder than you expect.
● Talk to clients and end-users
● Gather existing documentation
● Observe how future users work now
Make sure your interpretation is correct and complete!
Think about the other possibilities besides the Happy Flow.
Elicitation techniques
1. Asking (Interview/brainstorm/questionnaire)
2. Task analysis (what actions a user needs to do and how are they organized?)
3. Scenario-based analysis (What happens if …?)
4. Ethnography (actively observe what users are doing)
5. Analyse existing documents and systems (What are the problems with the current
system and/or methods?)
6. Prototyping (Check if this is what the customer wants)
7. Domain analysis (How do existing systems solve problems?)
12
Scenario - Narrative story that details what people do and how they experience as they
make use of the system and application
Use Case - more general; describes the interaction between users and the system that
produces some kind of result/value.
- Actors
- Anyone involved in the system (even other systems)
- Systems
- Use Cases
- Arrows
- Show the relationship between use cases.
Requirements validation
checks the requirements document on:
- Consistency
- Completeness
- Accuracy
Need to talk to customers and users and check if you covered everything
Requirements verification
is an (automatic) mathematical analysis to determine if the requirements are consistent.
13
4.4 Negotiation
Establish a sensible set of requirements that you can guarantee to deliver
Resolve conflicts between stakeholders
14
5 Object Oriented Design (OO-design)
OO design thinks in terms of objects and responsibilities first.
● We should think of object abstractly as managing responsibilities
● We can use the GRASP principles to assign responsibilities to the conceptual
classes in our domain model
Before making the design (or drawing class diagrams), create a domain model.
- Help you understand the world of the customer
- First step towards defining the system and in structure and data
- There are various ways to design these concepts in a computer program.
15
- A software system design aims to decompose a big problem into smaller
manageable pieces.
- If a design is tightly coupled or weakly cohesive, a minor change can
affect a lot of other parts of the system!
Functional Design
The idea behind functional design is to give each modular part of software a single
responsibility and make each part as independent as possible from the other parts.
- Each module should be strongly cohesive and loosely coupled.
Types of coupling:
● Data coupling - One method relies on the data produced somewhere else.
● Control coupling - One method tells the other what to do
● Global data coupling - Different methods access the same global variables
● Pathological coupling (worst) - One method relies on the exact implementation of
another method.
16
Loose coupling is important
5.3 Responsibility
Another way to decompose a problem into smaller parts is to look at responsibility.
- By designing classes, responsibilities are assigned to the classes.
Shalloway and Trott argue that these 3 levels are useful to understand objects.
1. Conceptual: view an object as a set of responsibilities
2. Specification: view an object as a set of methods
3. Implementation: view an object as a set of code and data.
OO-design thinks in terms of objects and responsibilities first.
Key question to ask during design: “Which class is responsible for what?”
These principles help assign responsibility to the classes in the domain model
1. Information Expert (who has the info?)
2. Creator (who is responsible to create instances)
3. Loose coupling
4. Strong cohesion
5. Controller (Which subsystem handles events and activities?)
Every design decision has pros and cons. A good design is about balancing the pros and
cons.
17
6 UML
Analysis and how to use UML
Create diagrams that visualizes the domain and the resulting software design.
Previously: How to translate requirements and use cases into a software design.
- What kind of notation can you use?
6.1 Analysis
Perform an analysis to come up with an abstract model of the problem’s domain.
- You have a bunch of requirements and use cases
- You want to translate those to a technical specification that is used by
developers.
- A good model simplifies reality, but represents all relevant data.
18
Different symbols of a activity diagram
You use activity diagrams in the Business Modeling Phase. There, you establish how
the current business processes work.
Modifiers
You can use modifiers to indicate the visibility of the methods and attributes of a class.
● + means Public
● - means Private
● # means protected
19
Relations between classes
1. Inheritance
- B is a subclass of A
- B is derived from A
- A is the superclass of B
2. Dependency
Vague relation (Often used: relation but no aggregation)
Dependency means:
- B depends on A, or
- B uses A in some way
4. Composition
A special form of aggregation.
Composition means:
- A has a B, but B cannot exist without A
20
Associations
Directed Associations
Associations can be directed.
● A knows B
● B knows A
● A and B know each other
Cardinalities
You can also write a number or range with any association.
Labeled associations
You can add labels to associations to clarify the nature of the associations
● A works for B
Undirected arrows
(Avoid if possible)
This can mean:
● The exact relation is undecided
● Both objects know about each other
21
7 Design Patterns
Design patterns are standard solutions to problems, which generally makes your software
easier to modify and maintain.
Upfront Design
What should you design upfront?
- If, according to the Agile Manifesto, you shouldnt focus too much on upfront design,
why are design patterns relevant?
- By learning Design Patterns, you will learn the qualities of good code and a
good design.
22
2. Favor aggregation over inheritance
3. Encapsulate the concept that varies
Design Patterns and Agile have a few key elements in common:
4. No redundancy (DRY)
a. Don’t repeat yourself: if you reuse code, encapsulate change-sensitive code
in a well defined interface.
5. Readability
b. Name objects and methods to their purpose.
c. Aim for short, cohesive methods
6. Testability
d. Loosely coupled and strongly cohesive methods are easier to test.
Types of encapsulation
1. Data encapsulation: Use private attributes to hide data
2. Use private methods to hide computation
3. Hide one object behind another (hiding hisStar behind Star)
4. Type encapsulation: The implementation of specific shapes behind an abstract class
Shape.
Focus on encapsulating the variables that can vary (e.g. the color, special border of a shape)
CVA, Commonality and Variability Analysis: Focus on what classes have in common and
what varies.
23
Facade Adapter Strategy Bridge Factory
Consequences The number Allow the Minimal use Objects don’t There is less
of interfaces use of of have to deal copy/pasting
you have to pre-existing conditionals, with , and
deal with are objects to fit all implementati stronger
being into new algorithms on issues. cohesion of
reduced class are being Extensibility classes.
structures called in the increases.
without same way,
being limited new
by their strategies
interface are easy to
implement
24
Implementation Create a Contain the Create an Create two Create an
facade class existing abstract strategies, abstract
which uses class into a class, and and relate factory class
the new class derive them with an with
interfaces of and make specific aggregation. concrete
subsystems that match strategy factory
to create a the wanted methods as subclasses.
simple interface subclasses Another
interface of that class. class which
uses there
concrete
strategies.
Structure
Facade variations
The facade can also reduce the number of subsystems you have to deal with, by creating
one facade where all the subsystems come together.
25
7.2 The Adapter Pattern
● Intent:
○ Convert one interface into another
■ This lets classes work together which otherwise couldn't (since their
interfaces weren’t compatible.
● Problem:
○ Classes are unable to work together.
● Solution
○ Create an “wrapper” around an existing class. Thos wrapper satisfies the right
syntax and is still able to use the original code from the class it wrapped
around.
● Consequences
○ Allows pre-existing objects to fit into new class structures without being
limited by their interface.
● Implementation
○ Contain the existing class in another class. Make the containing class match
the wanted interface.
26
7.3 The Strategy Pattern
Pattern which encapsulates variation according to the GRASP principles.
The strategy pattern defines all the different strategies/variations to do something (like
calculating tax) in subclasses of an abstract class CalcTax. The abstract class defines the
interface of the different strategies.
Strategy pattern separates the use of a calculation and the defining of a calculation.
● Intent
○ Use different rules/algorithms depending on the context
● Problem
○ Some computation depends on the client making the request
● Solution
○ Separate this selection of the algorithm from the implementation of the
algorithm.
● Participants
○ Abstract Strategy class
○ His subclasses with all one possible implementation
○ Context uses a specific variation of the implementation
● Consequences
○ Defines a family of algorithms
○ Minimal use of switches and if/else-conditionals
○ All algorithms are being called in the same way
27
7.4 The Bridge Pattern
The Bridge Pattern is a connection between 2 strategy patterns, so that the 2 strategies can
use each other without knowing the actual variations that are being used.
● Intent:
○ Decouple an abstraction from its implementation so they can vary
independently (Make two parts of a software system work together)
● Problem
○ The different subclasses of an abstract class must use multiple
implementations, without having to explode in a number of classes.
● Solution
○ Define an interface for all implementations to use and have the derivation of
the abstract class use that.
● Consequences
○ By decoupling implementation and abstraction, extensibility increases.
Objects are not aware of implementation issues.
Couple 2 things which vary through abstract classes, so that the coupling is looser.
28
7.5 The Abstract Factory
To separate the creation and the usage of objects.
- Loosening the coupling from
The Context class uses the factory to create the strategy it needs.
Decorator is de subclass van Component, maar heeft zelf ook een Component.
29
8 Design By Contract
How do you design “correct” software?
- Software meets its specifications
Hoare Logic
A logic language to proof statements about programs.
{P} C {Q}
Consists of 3 parts:
1. {P} = Precondition - state before the execution of the program
2. C = Program - the program
3. {Q} = Postcondition - state after the execution of of the program
30
Design by Contracts
A contract is:
Establish agreement between two parties.
- Expect certain benefits
- Willing to incur obligations to obtain those benefits
You can make these contracts (pre- and postconditions) explicit in Python:
● Assert statement - Check pre- and postconditions in code
○ The caller of the method is responsible for that the preconditions hold.
○ The method itself is responsible for that the postconditions hold.
■ Invariants:
● X is in the range {0..10}
● X <= 10
● X is an integer
● ...
31
9 System Design Methods
9.1 Refactoring
Changing existing code with the aim to improve it.
In practice, you more often than not will work in existing software, rather than creating some
from scratch.
Martin Fowler - “Refactoring: a change made to the internal structure of software to make it
easier to understand and cheaper to modify without changing its observable behavior.”
In short, Refactoring...
● Keeps your code clean
● Aims for self-documenting code:
○ choose meaningful names
○ Lift complex computations into separate methods
○ Keep control flow simple
○ …
● When refactoring, take small steps and test all the time.
Refactoring safely
It is easy to create bugs while refactoring codes.
Best way to refactor:
● Don’t start refactoring complex code, unless you have a way to test it.
● Refactor in small steps. Test and verify these small steps individually.
● Make sure that there is a revision history
● Test your program after each refactoring step to catch bugs as early as possible.
Reasons to refactor:
● Improve software design (eliminating duplicate code)
● Easier to understand
● Easier to adapt
● Easier to test
● Helps spotting bugs
● Supports faster programming
32
● Rule of three
○ 1st time you write something
○ 2nd time you notice you have to write duplicate code
○ 3rd time, you refactor
● When you add a new feature
● Fix a bug
● Do a code review
Bad code smells - Symptoms in the source code which may indicate bad design (not bugs)
● Keep a list of bad code smells in the back of your mind.
● Examples of bad code smells:
○ Duplication
■ Problem: Duplication
■ Fix: introduce a method
○ Long method (with a vague name)
■ Problem: Method is doing too much (weak cohesion)
■ Fix: Split to methods into smaller cohesive methods
○ Large class (with vague name)
■ Problem: Class is doing too much
■ Fix: Split the class into smaller, more cohesive, loosely coupled
classes.
○ Too many parameters
■ Problem: method is doing too much (weak cohesion)
■ Fix: Split the method into smaller cohesive methods
○ Shotgun surgery
■ Problem: introducing a new feature you need to update the existing
code in many different places.
■ Fix: Introduce strategy pattern
○ ,,,
■ Problem: Responsibility for the computation is in the wrong place
■ Fix: Put the computation in a separate method or use a Strategy
○ Comments
■ Problem: If a lot of comments are needed to explain what something is
doing, it is probably badly designed.
■ Fix: ?
○ Bad naming
■ Problem: names should explain what it’s for. Too long or too short
names don’t do that.
■ Fix: name classes, methods and variables to what they do or what
they are.
33
A few refactorings
● Introduce parameter object
○ If a method has many parameters, it is difficult to call.
○ Instead, group parameters into an object.
34
● Moving methods, fields or attributes
○ If something is too weakly cohesive
○ Extract class refactoring to extract attributes and store it in a new class.
● Pull-up refactoring
○ If all subclasses have the same method, it can be called in the superclass.
● Pull-down refactoring
○ If not all subclasses have a method, remove it from the superclass.
● Splitting classes
● Hiding delegates
35
9.2 Testing
Testing is about:
● Testing software
● What types of tests there are
● How to use tests to improve software design
Unit testing
● Test 1 unit at a time
● Write testing code for parts that might break (simple getters and setters don't need
testing)
● Testing code is code too
● Same design principles apply to testing code.
36
●
Coverage
● amount of code which is tested
● Organizations often have a coverage goal of 80% to ensure a level of stability etc.
● https://coverage.readthedocs.io/ is a python library for computing coverage reports.
Benefits of TDD
1. Forces developers to think about specifications first
2. Encourages better design (loosely coupled and strongly cohesive code is easier to
test)
3. Avoid the skimp of writing tests
4. Code will require less refactoring later
37
10 OO-Principles
When designing software:
1. Start with the big picture - a conceptual understanding of the whole
a. First think about which rooms a house should have, instead of which bricks to
use.
2. Identify patterns at this level
3. Start filling in details, identify patterns at this level, creating context
4. Work inward: repeatedly apply patterns, identify new patterns and repeat.
5. The final implementation is guided by the sequence of design patterns you chose to
apply.
SOLID-principles of OO-Design
(instead of the GRASP-principles)
● Single Responsibility - (Strong cohesion)
● Open/closed - Software is open for extension, closed for modification
○ Changing already existing strategies is more work/closed
● Liskov substitution - Don’t change the behavior of a superclass in a subclass.
● Interface segregation - to an interface, not an implementation
● Dependency inversion - Start with abstractions instead of implementations
○ High-level modules should not depend on low-level modules.
○ Abstractions shouldn't depend on details
○ Implementations are more likely to change than the abstract concepts.
38
3. Analysis Matrix
Fowler: Software architecture are the decisions which are hard to change.
So: Software architectural decisions are on a higher level than software design decisions.
- Establish how users will use the application
- Where the data is stored
- How to be deployed
- How to be maintained
39
Model-View-Controller Pattern
Used in applications to combine a GUI, database and business logic.
40
The Observer Pattern
Also Listener Pattern / Publish-Subscribe-model
Intent: Allows you to notify other objects when objects change.
- Alternatives: create a module of the classes where you only want 1 instance from.
41
The Object Pool Pattern
Manages the amount of instances you want to have.
42