Software Design Principles

Slides:



Advertisements
Similar presentations
1 Object-Oriented Reengineering © R. Marinescu Lecture 5 Radu Marinescu Principles of Object-Oriented Design.
Advertisements

General OO Concepts and Principles CSE301 University of Sunderland Harry R. Erwin, PhD.
Lecture 9 Improving Software Design CSC301-Winter 2011 – University of Toronto – Department of Computer Science Hesam C. Esfahani
SOLID Object Oriented Design Craig Berntson
5/17/2015 OO Design: Liskov Substitution Principle 1.
Testing and Inheritance What is the relation between the test suite of a superclass and a subclass?
Inheritance and object compatibility Object type compatibility An instance of a subclass can be used instead of an instance of the superclass, but not.
1 Evan Korth New York University Inheritance and Polymorphism Professor Evan Korth New York University.
1 Evan Korth New York University Inheritance and Polymorphism Professor Evan Korth New York University.
CSc 335: Three More OO Design Principles
1 OO Design Principles Project Group eXtreme Programming Md. Abul Bashar 07/09/2004.
CLASS DESIGN PRINCIPLES Lecture 2. The quality of the architecture What is a good design? It is the design that at least does not have signs of “bad”.
1 OO Design Novosoft, 2001 by V. Mukhortov. 2 OO Design Goals  Flexibility Changes must be localized  Maintainability Modules requiring changes can.
1 Abstraction  Identify important aspects and ignore the details  Permeates software development programming languages are abstractions built on hardware.
Company Confidential – Do Not Duplicate 2 Copyright 2008 McLane Advanced Technologies, LLC S.O.L.I.D. Software Development Achieving Object Oriented Principles,
Principles of Object-Oriented Design SEI, SJTU WEB APPS and SERVICES.
More Design. Next Tuesday First draft of architectural design –use cases –class diagrams for major classes with responsibilities –sequence diagrams for.
Object Orientation Yaodong Bi, Ph.D. Department of Computer Sciences University of Scranton October 18, 2015October 18, 2015October 18, 2015.
© 2004 Capgemini - All rights reserved SOLID - OO DESIGN PRINCIPLES Andreas Enbohm, Capgemini.
Chapter 9 Object-Oriented Software Development F Software Development Process F Analyze Relationships Among Objects F Class Development F Class Design.
Introduction to SOLID Principles. Background Dependency Inversion Principle Single Responsibility Principle Open/Closed Principle Liskov Substitution.
Class Design III: Advanced Inheritance Additional References “Object-Oriented Software Development Using Java”, Xiaoping Jia, Addison Wesley, 2002 “Core.
S.O.L.I.D. Software Development 12 January 2010 (Martin Verboon, Patrick Kalkman, Stan Verdiesen)
Design Principles iwongu at gmail dot com.
OO as a language for acm l OO phrase l Mental model of key concepts.
Software Design Principles
1 Single Responsibility Principle Open Closed Principle Liskov Substitution Principle Law of Demeter CSC 335: Object-Oriented Programming and Design.
Incremental Design Why incremental design? Goal of incremental design Tools for incremental design  UML diagrams  Design principles  Design patterns.
Elements of OO Abstraction Encapsulation Modularity Hierarchy: Inheritance & Aggregation 4 major/essential elements3 minor/helpful elements Typing Concurrency.
Testing and Inheritance What is the relation between the test suite of a superclass and a subclass?
OO Design Principles Copyright © Vyacheslav Mukhortov, Nikita Nyanchuk-Tatarskiy, Copyright © INTEKS LLC,
Ordered Linked Lists using Abstract Data Types (ADT) in Java Presented by: Andrew Aken.
Object Oriented Programming
Inheritance CSI 1101 Nour El Kadri. OOP  We have seen that object-oriented programming (OOP) helps organizing and maintaining large software systems.
1 Design by Principles (Robert Martin) Software Engineering.
Evaluating an Object-Oriented Design ©SoftMoore ConsultingSlide 1.
1. Perspectives on Design Principles – Semantic Invariants and Design Entropy Catalin Tudor 2.
PRINCIPLES OF OBJECT ORIENTED DESIGN S.O.L.I.D. S.O.L.I.D Principles What is SOLID?  Acrostic of 5 Principles:  The Single Responsibility Principle.
SOLID Design Principles
These courseware materials are to be used in conjunction with Software Engineering: A Practitioner’s Approach, 6/e and are provided with permission by.
Session 33 More on SOLID Steve Chenoweth Office: Moench Room F220 Phone: (812) Chandan Rupakheti Office: Moench.
Test Code Patterns How to design your test code. 2 Testing and Inheritance Should you retest inherited methods? Can you reuse superclass tests for inherited.
Subtype Polymorphism, Subtyping vs. Subclassing, Liskov Substitution Principle.
1 Advanced Object- oriented Design – Principles CS320 Fall 2005.
1 Advanced Object-oriented Design – Principles and Patterns OO Design Principles.
What is Agile Design? SRP OCP LSP DIP ISP
Course information Old exam Resit Report Result and walkthrough
Modern Programming Tools And Techniques-I
Inheritance ITI1121 Nour El Kadri.
Software Architecture & Difference from Design
Inheritance and Polymorphism
CSE687 - Object Oriented Design class notes Survey of the C++ Programming Language Jim Fawcett Spring 2004.
Chapter 11 Object-Oriented Design
Copyright © by Curt Hill
Object Orientation Yaodong Bi, Ph.D. Department of Computer Sciences
CSE 331 Subtyping slides created by Marty Stepp based on materials by M. Ernst, S. Reges, D. Notkin, R. Mercer, Wikipedia
Object Orientation Yaodong Bi, Ph.D. Department of Computer Sciences
Design by Contract Fall 2016 Version.
Inheritance Chapter 5.
Component-Level Design
Software Design Principles
Modeling with Inheritance
11/29/2018 © 2014 Microsoft Corporation. All rights reserved. Microsoft, Windows, and other product names are or may be registered trademarks and/or trademarks.
Subtype Polymorphism, Subtyping vs
Object Oriented Practices
Principles of Object-Oriented Design
A (partial) blueprint for dealing with change
Principles of Object-Oriented Design
Object Oriented Design & Analysis
CIS 110: Introduction to computer programming
Presentation transcript:

Software Design Principles August 28, 2017

Symptoms of Rotting Design Rigidity No change can be afforded anymore since it may cause cascading changes. Fragility A simple change breaks the software in many places Fragility leads to Rigidity Immobility A module cannot be easily reused because it has too baggage that depends on. It is more efficient to write a new one instead of reuse. Viscosity Viscosity of Design: It is harder to make changes in the way that preserves the good design than hacking. Viscosity of Environment: the IDE is slow and inefficient. Detours are used to avoid large re-compile for example.

Software design principles The single-responsibility principle The open-closed principle The Liskov substitution principle The dependency inversion principle The interface segregation principle

The single-responsibility principle “A class should have only one reason to change.” -- Robert Martin A responsibility = a reason to change Separate coupled responsibilities into separate classes Linux: every “module” should do just one thing and do it well.

The single-responsibility principle Example: Often we need to sort students by their name, or ssn. So one may make Class Student implement the Java Comparable interface. class Student implements Comparable { … int compareTo(Object o) { … } };

The single-responsibility principle Register Add(Course d, Student s); Student SSN Name getSSN() getName() major getMajor() int compareTo() Comparable int compareTo() When a new requirement needs to sort students in a different order, Student, Register, and AClient all need to be recompiled, even Register has nothing to do with any ordering of Students. AClient op() { ;} It invokes Collections.sort(aListofStudents);

Java Comparable Each time students are ordered differently, the compareTo method needs to be changed and Students needs to be recompiled and also its clients. Student is a business entity, it does not know in what order it should be sorted since the order of sorting is imposed by the client of Student. Cause of the problem: we bundled two separate responsibilities (i.e., a business entity and ordering) into one class – a violation of SRP

The single-responsibility principle Register Add(Course d, Student s); Comparator int compare(Object o1, Object o2) Student SSN Name getSSN() getName() major getMajor() StudentByName int compare(Object o1, Object o2) ClientA op() { ;} StudentBySSN int compare(Object o1, Object o2) The solution is to separate the two responsibilities into two separate classes and use another version of Collections.sort(). ClientB op() { ;} It invokes Collections.sort(aListofStudents, StudentBySSN);

The single-responsibility principle Computational Geometry Application Rectangle +draw():void +area():integer Graphical Application GUI Class Rectangle may be forced to make changes from two different unrelated sources. One is from the Computational Geometry Application (CGA). E.g., adding area function for length and width of type double. The other is from Graphical Application (GA). E.g., add draw() in Windows XP to the existing draw in X Windows. A change from either of the two source would still cause the other application to recompile.

The single-responsibility principle Computational Geometry Application Graphical Application Geometric Rectangle +area():double Graphic Rectangle +draw():void GUI Package CGA is no longer dependent on graphical side of Rectangle and thus it becomes independent of package GUI. Any change caused by graphical application no longer requires CGA to be recompiled. However, any changes from the CGA side may cause GA to be recompiled.

The single-responsibility principle Computational Geometry Application Graphical Application Rectangle -double length -double width +getLength():dobule +getWidth():dobule Geometric Rectangle +area():double Graphic Rectangle +draw():void GUI Class Rectangle contains the most primitive attributes and operations of rectangles. Classes GeometricRectangle and GraphicRectangle are independent of each other. A change from either side of CGA or GA, it would not cause the other side to be recompiled. NOTE: this does not violate LSP, since Rectangle does not have any client.

The open-closed principle “Software entities (classes, modules, functions, etc,) should be open for extension, but closed for modification.” – R. Martin To make a class open for extension, closed for modification, program the class to interfaces (or abstract classes), not implementation (concrete classes). “You can new features to existing code, without changing the existing code, but by only adding new code”. “Changes do not propagate into existing code that already works.” Abstraction is the key to the OCP.

Violation of the OCP Employee Faculty Staff Secretary Engineer +int EmpType Faculty +getOffice() Staff +getDept() Secretary +getTypeSpeed() Engineer +getEngTYpe() void printEmpRoster(Employee[] emps) { for (int i; i<emps.size(); i++) { if (emps[i].empType == FACULTY) printfFaculty((Faculty)emps[i]); else if (emps[i].empType ==STAFF) printStaff((Staff)emps[i]); else if (emps[i].empType == SECRETARY) printSecretary((Secretary)emps[i]); } What if we need to add Engineer??

OCP – Dynamic Polymorphism Employee +printInfo() Faculty +printInfo() Staff +printInfo() Secretary +printInfo Engineer +printInfo() void printEmpRoster(Employee[] emps) { for (int i; i<emps.size(); i++) { emps[i].printInfo(); } When Engineer is added, printEmpRoster() does not even need to recompile. PrintEmpRoster() is open to extension, closed for modification.

OCP – Dynamic Polymorphism Three versions of SORT sort(List list) Elements of list must implement Comparable interface sort(List list, StringComparator sc) Elements of list are not required to implement Comparable StringComparator orders objects of String only Sort(List list, Comparator comp) Comparator may compare objects of any type. Open to extension since it can sort objects of any type at any order specified in the second parameter.

OCP – Static Polymorphism Generics in Java public class LinkedList<E> { boolean add(E e); boolean add(int index, E e); boolean addFirst(E e); boolean addLast(E e); void clear(); E get(int index); ... } The container can take objects of any type.

The Liskov substitution principle “Subtypes must be substitutable for their base types.” – R. Martin Demand no more, promise no less Demand no more: the subclass would accept any arguments that the superclass would accept. Promise no less: Any assumption that is valid when the superclass is used must be valid when the subclass is used. Interface inheritance – The LSP should be conformed to. Implementation inheritance – use composition instead of inheritance (in Java) or use private base classes (in C++).

LSP – Design by Contract The contract of a method: Precondition: what must be true when calling it If the precondition fails, the results are undefined Postcondition: What are guaranteed to be true If the postcondition fails, it shall not return. The LSP in terms of contract A derived class is substitutable for its base class if Its preconditions are not stronger than the base class method Its postconditions are no weaker than the base class method.

The Liskov substitution principle Implementation inheritance When you use List to implement Queue (in Java), use composition, not inheritance. The intention is that you use only List’s implementation <foundation> List +insert() +delete() +find() List +insert() +delete() +find() List +insert() +delete() +find() MyList Queue +enqueue() +dequeue() +isEmpty() Queue +enqueue() +dequeue() +isEmpty() Queue +enqueue() +dequeue() +isEmpty()

The Liskov substitution principle class Square extends Rectangle { public void setWidth(int width) { super.setWidth(width); super.setHeight(width); } public void setHeight(int height) { super.setHeight(height); super.setWidth(height); void clientOfRectangle(Rectangle r) { r.setWidth(10); r.setHeight(20); print(r.area()); Rectangle r = new Square(…); clientOfRectangle(r); // what would be printed? Rectangle -int width; -int height +getWidth() +setWidth() +getHeight() +setHeight() +area(); IS-A Square +getWidth() +setWidth() +getHeight() +setHeight()

The Liskov substitution principle Rectangle and Square Invariant of Rectangle: width and height are independent of each other (which can be expected from the setWidth and setHeight operations) Square violates the width-height-independence invariant of Rectangle Design by Contract: The precondition (width == height) of the derived methods is stronger than that (width is independent of height) of the base methods

The Liskov substitution principle There are cases in which the substitutability may not be needed Specialization: we found that Faculty, Staff, Secretary and Engineer all have the same set of attributes and operations, so we created the Employee as a placeholder for those common properties. For the system, there is no client for Employee Thus, the four subclasses do not need to be substitutable Actually, there is no way we can tell whether they are or not. Employee +printInfo() Faculty +printInfo() Staff +printInfo() Secretary +printInfo Engineer +printInfo() Specialization

The dependency inversion principle “Abstraction should not depend on details. Details should depend on abstraction.” – R. Martin High-level concepts are more stable than low-level implementation

The dependency inversion principle Policy Layer High-level modules make calls to low-level modules. Mechanism Layer Utility Layer The upper-level layer is dependent upon lower-level layers.

The dependency inversion principle Dependency Inversion: Lower-level layers is dependent upon upper-level layers. Policy Policy Layer Mechanism Mechanism Layer <<interface>> Policy Service Utility <<interface>> Mechanism Service Utility Layer Ownership Inversion: The client (upper-level layer) owns the interface, not the lower-level layers

DIP and OCP High-level concepts are more stable than low-level implementation Concrete things change often and abstract things change less often. Abstractions are “hinge points”, places when the design can provide different implementations That is the OCP

The interface segregation principle “Clients should not be forced to depend on methods that they do not use.” – R. Martin When we bundle functions for different clients into one interface/class, we create unnecessary coupling among the clients. When one client causes the interface to change, all other clients are forced to recompile.

ISP – A Bad Design Service Methods For ClientA For ClientC Client A Client B Client C The problem is that any change in Service introduced by one client (e.g., Client A) causes Service and the other clients (Client A and Client C) to be recompiled.

ISP – A Good Design ServiceA Methods For ClientA ServiceImpl Methods For ClientA For ClientC Client A ServiceA Methods For ClientA Client B ServiceA Methods For ClientA Client C Changes introduced by one client (e.g., Client A) may require its designated interface (ServiceA) and the service implementation to change. However, other clients (Client A & Client C) and their Interfaces (ServiceB & ServiceC) are not required to change or recompile.

Software design principles - summary The single-responsibility principle There is only one source that may the class to change The open-closed principle Open to extension, closed for modification The Liskov substitution principle A subclass must substitutable for its base class The dependency inversion principle Low-level (implementation, utility) classes should be dependent on high-level (conceptual, policy) classes The interface segregation principle A client should not be forced to depend on methods it does not use.