2. www.luxoft.com
Why does software design matter and how to keep it in
good shape?
● Why does software design matter?
● What is system complexity?
● What is software quality?
● What is bad software design?
● What is good software design?
● What principles help to achieve good software design?
● How to keep software design in good shape?
● When to do refactoring?
3. www.luxoft.com
Difference between design and architecture
Software architecture is the high level structures of a software
system.
● What kind of data storage is used?
● How is caching implemented?
● How do modules interact with each other?
● How is high availability achieved?
4. www.luxoft.com
Difference between design and architecture
Software design refers to the design on the individual modules.
● What are the responsibilities of the modules?
● What are the responsibilities of the classes?
● What design patterns are used?
9. www.luxoft.com
Rigidity
● A design is rigid if it can not be easily changed.
● A single change begins a cascade of changes in dependent
packages.
● If the effort of that cascade of change can not be predicted by
designers and maintainers the impact of the change can not be
estimated. This makes the cost of the change impossible to
estimate.
10. www.luxoft.com
Fragility
● Fragility is the tendency of a program to break in many places
when a single change is made.
● Often the new problems are in areas that have no conceptual
relationship with the area that was changed.
● This leads to inability to predict the quality of the product.
● Simple changes to one part of the application lead to failures in
other parts appear to be completely unrelated.
● Fixing those problems leads to even more problems.
11. www.luxoft.com
Immobility
● A design is difficult to reuse when the desirable parts of the
design are highly dependent upon other details which are not
desired.
● Often the amount of work necessary to separate the desirable
portion of the design from the other portions of the design that
are undesirable design is high.
12. www.luxoft.com
What is reusability?
● Reusability is one of the most important goals of OOD.
● Copying a bunch of code from one program and textually
inserting it into another is not a reuse it is copying.
● When code is copied it becomes yours.
● You have to change it, fix bugs and add new features instead of
original author.
● The code is reused if, and only if, developer doesn’t need to look
at the source code, but needs only include library.
13. www.luxoft.com
Viscosity
One more symptom of bad software design is viscosity.
There are 2 types of viscosity:
● viscosity of the design,
● viscosity of the environment.
14. www.luxoft.com
Viscosity of the design
● Viscosity of the design refers to the ease at which a developer
can add design-preserving code to a system.
● Design has high viscosity, if design preserving methods are
harder to employ than the hacks.
● Engineers usually find more than one way to make the change.
● Some of the ways preserve the design, others do not and are
hacks.
15. www.luxoft.com
Viscosity of the environment
● Viscosity of the environment refers to performance and
effectiveness of development environment.
● Viscosity of the environment is high if development
environment is slow and inefficient.
18. www.luxoft.com
Fundamental principles of OOP
Object-oriented programming is a programming paradigm based
on using objects that are instances of classes, consisting of fields,
methods, and their interaction for designing applications.
Fundamental principles of OOP:
● Abstraction
● Encapsulation
● Inheritance
● Polymorphysm
19. www.luxoft.com
Abstraction
● Abstraction is a fundamental principle of software
development that allows to reduce coupling between software
modules.
● Abstraction is formulation of generalized concept disregarding
not important features, properties and relations in order to
focus on distinctive features.
● Abstraction captures only those details about an object that are
relevant to the current perspective.
20. www.luxoft.com
Abstraction
● Abstraction is an interface to data type or functionality and can
have multiple implementations.
● Concrete implementation is never referenced directly and can
be replaced with another implementation without requiring
changes in client code.
● Client code should depend on abstraction, not the particular
implementation.
22. www.luxoft.com
The principles of OOD
● Principles of class design;
● Principles about package cohesion, telling what to put into
packages;
● Principles about the coupling between packages.
23. www.luxoft.com
Principles of class design
● The Single Responsibility Principle
● The Open Closed Principle
● The Liskov Substitution Principle
● The Interface Segregation Principle
● The Dependency Inversion Principle
These 5 principles are also known as SOLID principles.
24. www.luxoft.com
The Single Responsibility Principle (SRP)
A class should have only one reason to change.
● A responsibility is “a reason to change”.
● If there are more than one motive for changing a class, then
that class has more than one responsibility.
● This principle also called cohesion.
● Cohesion is the functional relatedness of the elements of a
module.
25. www.luxoft.com
The Open-Closed Principle
Software entities (classes, modules, functions etc.) should be open
for extension, but closed for modification.
● The behaviour of modules is changed by adding new code, not
by changing old code that already works.
● Such modules can be created by using abstract classes, Strategy
pattern (GoF) etc.
26. www.luxoft.com
The Liskov Substitution Principle (LSP)
Functions that use pointers or references to base classes must be
able to use objects of derived classes without knowing it.
● This principle is also known as “Design by Contract”.
● Any function which uses a base class must not be confused
when a derived class is substituted for the base class.
27. www.luxoft.com
The Interface Segregation Principle (IPS)
Clients should not be forced to depend upon interfaces that they
do not use.
● Classes that have fat interfaces are not cohesive and the
interfaces of the class can be broken up into groups of member
functions. Each group serving a different set of clients.
● There are objects that requires non-cohesive interfaces, but
clients should not know about them as a single class, but should
know about cohesive implemented interfaces instead.
28. www.luxoft.com
The Dependency Inversion Principle (DIP)
● High level modules should not depend upon low level modules.
Both should depend upon abstraction.
● Abstractions should not depend upon details. Details should
depend upon abstraction.
29. www.luxoft.com
The Dependency Inversion Principle (DIP)
When this principle is adhered to, both the high level policy modules, and the
low level detail modules will be reusable and maintainable.
30. www.luxoft.com
Coupling
● OCP, ISP and DIP principles are related to coupling.
● Coupling refers to the degree of direct knowledge that one
component has of another.
● An example of tight coupling occurs when a dependent class
contains a pointer directly to a concrete class which provides
the required behavior.
● Loose coupling occurs when the dependent class contains a
pointer only to an interface, which can then be implemented by
one or many concrete classes.
31. www.luxoft.com
Principles about package cohesion
In this context a package is a binary deliverable like a .jar file.
● The Reuse/Release Equivalence Principle
● The Common Reuse Principle
● The Common Closure Principle
32. www.luxoft.com
The Reuse/Release Equivalence Principle (REP)
The granule of reuse is the granule of release. Only components
that are released through a tracking system can be effectively
reused. This granuli is the package.
33. www.luxoft.com
The Common Reuse Principle (CRP)
The classes in a package are reused together. If you reuse one of
the classes in a package, you reuse them all.
34. www.luxoft.com
The Common Closure Principle (CCP)
The classes in a package should be closed together against the
same kinds of changes. A change that affects a package affects all
the classes in that package.
35. www.luxoft.com
Principles about the couplings between packages
● The Acyclic Dependencies Principle
● The Stable Dependencies Principle
● The Stable Abstraction Principle
36. www.luxoft.com
The Acyclic Dependencies Principle (ADP)
The dependency structure between packages must be a Direct
Acyclic Graph (DAG). That is, there must be no cycles in the
dependency structure.
40. www.luxoft.com
Stability
● Stability is a measure of the difficulty in changing a module.
● Stability is not a measure of likelihood that a module will
change.
41. www.luxoft.com
Stability
● Afferent Coupling (Ca) - the number of classes outside this
package that depend upon classes within this package.
● Efferent coupling (Ce) - the number of classes inside this
package that depend upon classes outside this package.
● Instability (I) - has the range [0, 1]. 0 indicates a maximally
stable package. 1 indicates a maximally instable package.
● I = Ce / (Ca + Ce)
42. www.luxoft.com
The Stable Dependencies Principle (SDP)
The dependencies between packages in a design should be in the
direction of the stability of the packages. A package should only
depend upon packages that are more stable than it is.
43. www.luxoft.com
The Stable Abstraction Principle (SAP)
Packages that are maximally stable should be maximally abstract.
Unstable packages should be concrete. The abstraction of a
package should be in proportion to its stability.
44. www.luxoft.com
Symptoms of bad software design
● If it is hard to come up with the name of class or method
probably the abstraction is wrong and design requires changes.
● If you can’t find a name for a class or method maybe it is
unnecessary.
● If it is hard to write unit tests, then the responsibilities are
assigned to classes incorrectly and design doesn’t follow the
principles of OOD.
45. www.luxoft.com
Symptoms of bad software design
● The name of the unit test method is crucially important.
● If you can’t find good descriptive name for test that can be
treated as a requirements probably the test is unnecessary or
the abstraction is wrong.
● Good unit test can serve as documentation.
46. www.luxoft.com
More information about principles of OOD
http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod
Agile Principles, Patterns, and Practices in C#
by Robert C. Martin and Micah Martin
ISBN-13: 978-0131857254
ISBN-10: 0131857258
47. www.luxoft.com
How to keep software design in good shape?
● Pay off technical debt;
● Opportunistic refactoring.
49. www.luxoft.com
Technical debt
● Doing things quickly but dirty will result in additional work in
future required to make design cleaner that can be considered
as debt.
● The technical debt will come in the form of the extra effort in
future development because of the quick and dirty design
choice.
● Developers can choose technical debt in order to hit deadline
understanding the consequences.
50. www.luxoft.com
When to pay technical debt off?
● It is very important to not let technical debt get out of control
and spend time in future development paying debt off.
● Not paying attention to technical debt will result in increasing
system complexity and decreasing quality.
● There is a payoff deadline when losses on extra development
become more than benefits on taking technical debt.
52. www.luxoft.com
Example of managing technical debt in agile project
80% of the total team’s capacity can be spent on features
development and 20% on technical debt pay off.
53. www.luxoft.com
Use refactoring to keep a design clean
● Code refactoring is the process of restructuring existing
computer code without changing its external behavior.
● Refactoring improves code readability and reduces complexity,
improves code maintainability and allows to keep design clean.
54. www.luxoft.com
Refactoring techniques
Techniques that allow for more abstraction:
● Encapsulate Fields;
● Extract Interface/Supercalss sharing;
● Use Supertype where possible;
● Replace type-checking code with State/Strategy;
● Replace conditional with polymorphism;
● Replace Constructor with Factory;
● Replace Constructor with Builder.
55. www.luxoft.com
Refactoring techniques
Techniques for breaking code apart into more logical pieces:
● Introduce Method – turn part of a larger method into a new
method. By breaking down code in smaller pieces, it is more
easily understandable;
● Introduce Variable/Constant/Field.
56. www.luxoft.com
Refactoring techniques
Techniques for improving names and location of code:
● Move Class/Method/Field/Variable – move to a more
appropriate Class or source file;
● Rename Class/Method/Field/Variable – changing the name into
a new one that better reveals its purpose;
● Change Method signature;
● Pull Up – in OOP, move to a superclass;
● Push Down – in OOP, move to a subclass.
57. www.luxoft.com
When to do refactoring?
● Opportunistic refactoring means that at any time someone
sees some code that isn't as clear as it should be, they should
take the opportunity to fix it right there and then - or at least
within a few minutes.
● Also known as “boy-scout rule” - always leave the code behind
in a better state than you found it.
● If everyone on the team is doing this, they make small regular
contributions to code base health every day.
58. www.luxoft.com
Groupthink
● Groupthink is a psychological phenomenon that occurs within a
group of people, in which the desire for harmony or conformity
in the group results in an irrational or dysfunctional decision-
making outcome.
● Group members try to minimize conflict and reach a consensus
decision without critical evaluation of alternative viewpoints, by
actively suppressing dissenting viewpoints, and by isolating
themselves from outside influences.
59. www.luxoft.com
Groupthink
1. Leaders should assign each member the role of "critical evaluator". This allows each
member to freely air objections and doubts.
2. Leaders should not express an opinion when assigning a task to a group.
3. Leaders should absent themselves from many of the group meetings to avoid
excessively influencing the outcome.
4. The organization should set up several independent groups, working on the same
problem.
5. All effective alternatives should be examined.
6. Each member should discuss the group's ideas with trusted people outside of the
group.
7. The group should invite outside experts into meetings. Group members should be
allowed to discuss with and question the outside experts.