KEMBAR78
The maze of Design Patterns & SOLID Principles | PDF
The Maze of Design Patterns and
SOLID Principles
Shubham Dubey
Researcher and Course Instructor
University of Debrecen, Hungary
0. Software Crises
1. SOLID Principles
2. Design Patterns
3. Types of DPs
4. Novel Approaches of Development
Agenda
Software crises...
THE NIGHTMARES
The rate of failure was 70-80% in
seventies which almost reduced up to
50% nowadays.
Causes behind Software crises
• Over Budget
• Over time
• Ineffective and Hard to
maintain
• Does not meet requirements
• Rapid Changing Environmental
needs
• Misunderstandings
• Complex system
Attributes of successful products
Architecture
Design Principles
Design Patterns
SOLID
❑ SOLID is set of design principles that enables us to solve
most of the design problems.
SOLID is an acronym of 5 design
principles.
▪ Single Responsibility principle.
▪ Open/Closed principle.
▪ Liskov Substitution principle.
▪ Interface Segregation principle.
▪ Dependency Inversion principle.
What if we do not follow SOLID..?
• We end up with a tightly coupled
code
• This tight coupling causes time to
implement new requirements and
sometime bugs
• End up with a code which is not
testable
• End up with new bugs while fixing
another bug(s)
SOLIDs facilitate us
• Complexity reduction
• Increased reliability,extensibility and
maintenance
• Reduced bugs and implement
reusability
• Reduced tight coupling
• Parallel Development
Single Responsibility Principle
Interface Iuser
{
bool Login{string username, string password};
bool Register {string username, string password, string email};
void LogErr{string error};
bool SendEmail{string emailbody};
}
Implementing SRP
Interface Iuser
{
bool Login {string username, string password};
bool Register {string username, string password, string email};
}
Interface Ilogger
{
void LogErr {string error};
}
Interface IEmail
{
bool SendEmail {string emailbody};
}
Open Close principle
Guidelines for Implementation
Implement new functionality in new classes
Allow clients to access the original class with abstract interface
Open Close principle
public double Area (object[] shapes)
{
double area = 0;
foreach (var shape in shapes)
if (shape is Rectangle)
{
Rectangle rectangle = (Rectangle) shape;
area = area + rectangle.Breadth * rectangle.Length;
}
else
{ Circle circle = (Circle) shape;
area = area + circle.Radius * circle.Radius * PI;
}
return area;
}
Implementation of OCP
public abstract class Shape
{
public abstract double Area ();
}
public class Rectangle: Shape
{
public double Breadth {get; set; }
public double Length {get; set; }
public override double Area ()
{ return Breadth*Length;}
}
public class Circle: Shape
{
public double Radius {get; set;}
public override double Area ()
{ return Radius*Radius*PI;}
}
public double Area (Shape[] shapes)
{
double area = 0 ;
foreach (var shape in shapes)
{area = area + shape.Area ();}
return area;
}
Liskov Substitution Principle
S is a subtype of T, then objects of type T may be replaced by type S
Guidelines for Implementation
Client should not know which specific subtype they are calling.
New derived classes just extend without replacing the functionality of old classes.
Imlementing LSP
Animal a = new Animal(); can be replaced as
Animal a = new Buffalo();
Because the child type objects have all the properties
of themselves along with inherited properties of base
class. Here If we will talk about Buffalo class object it
has the properties has_legs(), has_teeth() and
gives_milk() because it inherits the properties of base
class.
So a.has_legs(); and a.has_teeth(); will
work well.
Dog d = new Animal ();
d.bark(); cannot work because all the animal type
object hasn’t the bark() property.
Interface Segregation Principle
"No client should be forced to depend on the interfaces it doesn’t use ’
“Many client specific interfaces are better than one general purpose interface”
Guidelines for Implementation
One fat interface need to be split into many smaller interface
Implementing ISP
interface Rotatable
{
void rotateslow();
void rotatefast();
}
class TableFan implements Rotatable
{
public void rotateslow(){/* rotating slow */ }
public void rotatefast(){/* rotating fast */ }
}
class ManualHandFan implements Rotatable
{
public void rotateslow(){/* rotating slow */ }
public void rotatefast(){/* we have to keep this as blank because
a hand fan cannot rotate fast*/ }
}
class Client
{
Rotatable r = new ManualHandFan();
}
As one can see here the client is unnecessarily dependent on
rotatefast() method. If ManualHandFan class is not
implementing the rotatefast() method then there is no need
to be dependent on it.
interface SlowRotatable
{
void rotateslow();
}
--------------------------------------------------------------------------------
interface FastRotatable
{
void rotatefast();
}
--------------------------------------------------------------------------------
class Table_fan implements SlowRotatable , FastRotatable
{
public void rotateslow(){/* rotating slow */ }
public void rotatefast(){/* rotating fast */ }
}
class ManualHandFan implements SlowRotatable
{
public void rotateslow(){/* rotating slow */ }
}
class Client
{
SlowRotatable s = new ManualHandFan();
}
Dependency Inversion Principle
“High-level modules should not depend on low-level modules. Both should depend on abstractions
also the Abstractions should not depend on details. Details should depend on abstractions”
Guidelines for Implementation
There could be an interaction through abstraction between high level and low level
modules, in order to achieve better and robust design.
Implementing DIP
Design Pattern
Design patternsare solutions of typical problems that we face during product development.
Creational Design Patterns Structural Design Patterns Behavioral Design Patterns
These patterns provide various
object creation mechanisms, which
increase flexibility and reuse of
existing code.
These patterns explain how to assemble
objects and classes into larger structures
while keeping these structures flexible and
efficient.
These patterns are concerned with
algorithms and the assignment of
responsibilities between objects.
Factory Method Pattern.
Abstract Factory Pattern.
Singleton Pattern.
Prototype Pattern.
Builder Pattern.
Object Pool Pattern.
Adapter Pattern.
Bridge Pattern.
Composite Pattern.
Decorator Pattern.
Facade Pattern.
Flyweight Pattern.
proxy Pattern.
Chain of Responsibility Pattern
Command Pattern
Interpreter Pattern
Iterator Pattern
Mediator Pattern
Memento Pattern
Observer Pattern
State Pattern
Strategy Pattern
Template Pattern
Visitor Pattern
Null Object
Singleton Pattern
• A class of which only and only one object can exist.
• Applicability: President of a country, Admin of a system
• As: In Java we can have only one system class java.lang.System
Guidelines for Implementation
• Make private constructor
• But if there is no method in the class then no instance can be used in this situation
we use class-level method getInstance() method.
We should avoid singleton usually because code becomes very difficult for
unit testing.
Prototype Pattern
• It is used to create or clone a copy of fully initialized
object or instance.
• Applicability:Sometimes creation becomes time
consuming then we clone the initialized instance.
• As: In the game of chess the beginning arrangements
of pieces are fixed and cloned every time when we start
a new game. set_Pieces() fully initialised object call.
Guidelines for Implementation
• Use either Deep or Shallow copy. When we pass the old
objects in the method this called Shallow copy and in we pass
new object then it is called Deep copy.
Factory Method Pattern
• It says define an interface or abstract classnor creating
an object but let the subclasses decide which class
to instantiate.
• Applicability: Flexibility in object instantiation.
• As: MSWord when we create a word file it
initializes word file but in case of excell it open sheet.
Guidelines for Implementation
• We create factory pattern when objects need to be extended to
the subclasses.
• The classes does not know what exact subclass it has to create.
• The product implementation tends to change overtime but
client remains unchanged.
Adapter Pattern
• Converts interface or a class into another interface that
a client wants.
• Applicability: Allows reusability
of existing functionality and enables two or
more previously incompaitable intergace to interact.
Guidelines for Implementation
• Use the pattern when you want to
reuse several existing subclasses that
lack some common functionality that
can’t be added to the superclass.
Decorator Pattern
• Decorator says attach a flexible additional responsibility to
an object dynamically. It is also called Wrapper.
• Applicability: Flexibility of dynamic property addition.
• As: Adding arnaments and lighting in x-mas tree.
Guidelines for Implementation
Two types of Implementation:
• Either expand the responsibilities in existing methods.
• Add new methods in existing ones.
State Pattern
• Alters an object behavior when its state changes.
• Applicability: when operation has huge conditional
branches that dependes on the objects state.
• As: Adding arnaments and lighting in x-mas tree.
Guidelines for Implementation
• The state object can be shared.
• It always increases the number of classes so do not use
unnecessarily.
Template Method Pattern
• It is used when we have a general receipt and we can make
similar products based on it.
• Applicability: More flexible and reliable code
• As: Tea and Coffee, add_Coffee() and add_Tea() are different
but add_milk(), add_sugar(), add_water() are comman and
same.
Guidelines for Implementation
Template methods have 3 steps
• Obligatory and Comman
• Obligatory and not comman
• Optional
This pattern has algorithms in which the steps are the same but content of the steps is
diferent. If a new step comes in then it will be a Hook() method.
The whole
picture
Keep Learning and
Sharing
Your Questions.?

The maze of Design Patterns & SOLID Principles

  • 1.
    The Maze ofDesign Patterns and SOLID Principles Shubham Dubey Researcher and Course Instructor University of Debrecen, Hungary
  • 2.
    0. Software Crises 1.SOLID Principles 2. Design Patterns 3. Types of DPs 4. Novel Approaches of Development Agenda
  • 3.
    Software crises... THE NIGHTMARES Therate of failure was 70-80% in seventies which almost reduced up to 50% nowadays.
  • 4.
    Causes behind Softwarecrises • Over Budget • Over time • Ineffective and Hard to maintain • Does not meet requirements • Rapid Changing Environmental needs • Misunderstandings • Complex system
  • 5.
    Attributes of successfulproducts Architecture Design Principles Design Patterns
  • 6.
    SOLID ❑ SOLID isset of design principles that enables us to solve most of the design problems. SOLID is an acronym of 5 design principles. ▪ Single Responsibility principle. ▪ Open/Closed principle. ▪ Liskov Substitution principle. ▪ Interface Segregation principle. ▪ Dependency Inversion principle.
  • 7.
    What if wedo not follow SOLID..? • We end up with a tightly coupled code • This tight coupling causes time to implement new requirements and sometime bugs • End up with a code which is not testable • End up with new bugs while fixing another bug(s) SOLIDs facilitate us • Complexity reduction • Increased reliability,extensibility and maintenance • Reduced bugs and implement reusability • Reduced tight coupling • Parallel Development
  • 8.
    Single Responsibility Principle InterfaceIuser { bool Login{string username, string password}; bool Register {string username, string password, string email}; void LogErr{string error}; bool SendEmail{string emailbody}; }
  • 9.
    Implementing SRP Interface Iuser { boolLogin {string username, string password}; bool Register {string username, string password, string email}; } Interface Ilogger { void LogErr {string error}; } Interface IEmail { bool SendEmail {string emailbody}; }
  • 10.
    Open Close principle Guidelinesfor Implementation Implement new functionality in new classes Allow clients to access the original class with abstract interface
  • 11.
    Open Close principle publicdouble Area (object[] shapes) { double area = 0; foreach (var shape in shapes) if (shape is Rectangle) { Rectangle rectangle = (Rectangle) shape; area = area + rectangle.Breadth * rectangle.Length; } else { Circle circle = (Circle) shape; area = area + circle.Radius * circle.Radius * PI; } return area; }
  • 12.
    Implementation of OCP publicabstract class Shape { public abstract double Area (); } public class Rectangle: Shape { public double Breadth {get; set; } public double Length {get; set; } public override double Area () { return Breadth*Length;} } public class Circle: Shape { public double Radius {get; set;} public override double Area () { return Radius*Radius*PI;} } public double Area (Shape[] shapes) { double area = 0 ; foreach (var shape in shapes) {area = area + shape.Area ();} return area; }
  • 13.
    Liskov Substitution Principle Sis a subtype of T, then objects of type T may be replaced by type S Guidelines for Implementation Client should not know which specific subtype they are calling. New derived classes just extend without replacing the functionality of old classes.
  • 14.
    Imlementing LSP Animal a= new Animal(); can be replaced as Animal a = new Buffalo(); Because the child type objects have all the properties of themselves along with inherited properties of base class. Here If we will talk about Buffalo class object it has the properties has_legs(), has_teeth() and gives_milk() because it inherits the properties of base class. So a.has_legs(); and a.has_teeth(); will work well. Dog d = new Animal (); d.bark(); cannot work because all the animal type object hasn’t the bark() property.
  • 15.
    Interface Segregation Principle "Noclient should be forced to depend on the interfaces it doesn’t use ’ “Many client specific interfaces are better than one general purpose interface” Guidelines for Implementation One fat interface need to be split into many smaller interface
  • 16.
    Implementing ISP interface Rotatable { voidrotateslow(); void rotatefast(); } class TableFan implements Rotatable { public void rotateslow(){/* rotating slow */ } public void rotatefast(){/* rotating fast */ } } class ManualHandFan implements Rotatable { public void rotateslow(){/* rotating slow */ } public void rotatefast(){/* we have to keep this as blank because a hand fan cannot rotate fast*/ } } class Client { Rotatable r = new ManualHandFan(); } As one can see here the client is unnecessarily dependent on rotatefast() method. If ManualHandFan class is not implementing the rotatefast() method then there is no need to be dependent on it. interface SlowRotatable { void rotateslow(); } -------------------------------------------------------------------------------- interface FastRotatable { void rotatefast(); } -------------------------------------------------------------------------------- class Table_fan implements SlowRotatable , FastRotatable { public void rotateslow(){/* rotating slow */ } public void rotatefast(){/* rotating fast */ } } class ManualHandFan implements SlowRotatable { public void rotateslow(){/* rotating slow */ } } class Client { SlowRotatable s = new ManualHandFan(); }
  • 17.
    Dependency Inversion Principle “High-levelmodules should not depend on low-level modules. Both should depend on abstractions also the Abstractions should not depend on details. Details should depend on abstractions” Guidelines for Implementation There could be an interaction through abstraction between high level and low level modules, in order to achieve better and robust design.
  • 18.
  • 19.
    Design Pattern Design patternsaresolutions of typical problems that we face during product development. Creational Design Patterns Structural Design Patterns Behavioral Design Patterns These patterns provide various object creation mechanisms, which increase flexibility and reuse of existing code. These patterns explain how to assemble objects and classes into larger structures while keeping these structures flexible and efficient. These patterns are concerned with algorithms and the assignment of responsibilities between objects. Factory Method Pattern. Abstract Factory Pattern. Singleton Pattern. Prototype Pattern. Builder Pattern. Object Pool Pattern. Adapter Pattern. Bridge Pattern. Composite Pattern. Decorator Pattern. Facade Pattern. Flyweight Pattern. proxy Pattern. Chain of Responsibility Pattern Command Pattern Interpreter Pattern Iterator Pattern Mediator Pattern Memento Pattern Observer Pattern State Pattern Strategy Pattern Template Pattern Visitor Pattern Null Object
  • 20.
    Singleton Pattern • Aclass of which only and only one object can exist. • Applicability: President of a country, Admin of a system • As: In Java we can have only one system class java.lang.System Guidelines for Implementation • Make private constructor • But if there is no method in the class then no instance can be used in this situation we use class-level method getInstance() method. We should avoid singleton usually because code becomes very difficult for unit testing.
  • 21.
    Prototype Pattern • Itis used to create or clone a copy of fully initialized object or instance. • Applicability:Sometimes creation becomes time consuming then we clone the initialized instance. • As: In the game of chess the beginning arrangements of pieces are fixed and cloned every time when we start a new game. set_Pieces() fully initialised object call. Guidelines for Implementation • Use either Deep or Shallow copy. When we pass the old objects in the method this called Shallow copy and in we pass new object then it is called Deep copy.
  • 22.
    Factory Method Pattern •It says define an interface or abstract classnor creating an object but let the subclasses decide which class to instantiate. • Applicability: Flexibility in object instantiation. • As: MSWord when we create a word file it initializes word file but in case of excell it open sheet. Guidelines for Implementation • We create factory pattern when objects need to be extended to the subclasses. • The classes does not know what exact subclass it has to create. • The product implementation tends to change overtime but client remains unchanged.
  • 23.
    Adapter Pattern • Convertsinterface or a class into another interface that a client wants. • Applicability: Allows reusability of existing functionality and enables two or more previously incompaitable intergace to interact. Guidelines for Implementation • Use the pattern when you want to reuse several existing subclasses that lack some common functionality that can’t be added to the superclass.
  • 24.
    Decorator Pattern • Decoratorsays attach a flexible additional responsibility to an object dynamically. It is also called Wrapper. • Applicability: Flexibility of dynamic property addition. • As: Adding arnaments and lighting in x-mas tree. Guidelines for Implementation Two types of Implementation: • Either expand the responsibilities in existing methods. • Add new methods in existing ones.
  • 25.
    State Pattern • Altersan object behavior when its state changes. • Applicability: when operation has huge conditional branches that dependes on the objects state. • As: Adding arnaments and lighting in x-mas tree. Guidelines for Implementation • The state object can be shared. • It always increases the number of classes so do not use unnecessarily.
  • 26.
    Template Method Pattern •It is used when we have a general receipt and we can make similar products based on it. • Applicability: More flexible and reliable code • As: Tea and Coffee, add_Coffee() and add_Tea() are different but add_milk(), add_sugar(), add_water() are comman and same. Guidelines for Implementation Template methods have 3 steps • Obligatory and Comman • Obligatory and not comman • Optional This pattern has algorithms in which the steps are the same but content of the steps is diferent. If a new step comes in then it will be a Hook() method.
  • 27.
  • 28.
  • 29.