Design Principles.

Slides:



Advertisements
Similar presentations
CS Design Principles Hans Van Vliet, Software Engineering, Principles and Practice, 3 rd edition, John Wiley & Sons, Section Robert C.
Advertisements

Object-Oriented Analysis and Design
From Theory to Practice 1 OOP Overview Reminder – some OOD principles from previous lessons: –Class Inheritance vs. Object Composition –Program.
3/15/05H-1 © 2001 T. Horton CS 494 Object-Oriented Analysis & Design Evaluating Class Diagrams Topics include: Cohesion, Coupling Law of Demeter (handout)
Programming Languages and Paradigms Object-Oriented Programming.
1 OO Design Principles Project Group eXtreme Programming Md. Abul Bashar 07/09/2004.
Introduction to Object-oriented programming and software development Lecture 1.
Introduction to Object Oriented Programming. Object Oriented Programming Technique used to develop programs revolving around the real world entities In.
1 Object-Oriented Software Engineering CS Interfaces Interfaces are contracts Contracts between software groups Defines how software interacts with.
Features of Object Oriented Programming Lec.4. ABSTRACTION AND ENCAPSULATION Computer programs can be very complex, perhaps the most complicated artifact.
Effective C#, Chapter 1: C# Language Elements Last Updated: Fall 2011.
Inheritance - Polymorphism ITI 1121 Nour El Kadri.
1 Computer Science 340 Software Design & Testing Inheritance.
CSSE501 Object-Oriented Development. Some OO Design Principles  Majority principles here come from: Design Principles in Java, Bob Tarr.
Implications of Inheritance COMP206, Geoff Holmes and Bernhard Pfahringer.
More Implications of Inheritance COMP204, Bernhard Pfahringer.
Design Patterns Gang Qian Department of Computer Science University of Central Oklahoma.
Elements of OO Abstraction Encapsulation Modularity Hierarchy: Inheritance & Aggregation 4 major/essential elements3 minor/helpful elements Typing Concurrency.
Inheritance CSI 1101 Nour El Kadri. OOP  We have seen that object-oriented programming (OOP) helps organizing and maintaining large software systems.
Application development with Java Lecture 21. Inheritance Subclasses Overriding Object class.
Effective Java, Chapter 4: Classes and Interfaces Last Updated: Fall 2011.
Topics Inheritance introduction
Evaluating an Object-Oriented Design ©SoftMoore ConsultingSlide 1.
COM S 228 Introduction to Data Structures Instructor: Ying Cai Department of Computer Science Iowa State University Office: Atanasoff.
Lecture 2 Object-oriented programming. Definitions of OOP OOP is a programming paradigm, which utilizes encapsulation, inheritance and polymorphism. (From.
StarBuzz Coffee Recipe Boil some water Brew coffee in boiling water Pour coffee in cup Add sugar and milk Tea Recipe Boil some water Steep tea in boiling.
CSI 3125, Preliminaries, page 1 Inheritance. CSI 3125, Preliminaries, page 2 Inheritance Using inheritance, can create a general class that defines traits.
Inheritance ndex.html ndex.htmland “Java.
Terms and Rules II Professor Evan Korth New York University (All rights reserved)
CSC 205 Java Programming II Abstract Data Type. Abstraction The meaning of abstraction Abstraction arises from a recognition of similarities between certain.
Polymorphism 1. Reuse of code: every time a new sub-class is defined, programmers are reusing the code in a super-class. All non-private members of a.
Zach Tatlock / Winter 2016 CSE 331 Software Design and Implementation Lecture 12 Subtypes and Subclasses.
Java Programming: Guided Learning with Early Objects Chapter 9 Inheritance and Polymorphism.
Class Inheritance Part II: Overriding and Polymorphism Corresponds with Chapter 10.
Modern Programming Tools And Techniques-I
CompSci 280 S Introduction to Software Development
Sections Inheritance and Abstract Classes
Module Road Map Refactoring Why Refactoring? Examples
Inheritance ITI1121 Nour El Kadri.
Topic: Classes and Objects TALENTSPRINT | © Copyright 2012
Inheritance and Polymorphism
Chapter 11 Object-Oriented Design
CMPE 135: Object-Oriented Analysis and Design October 24 Class Meeting
Copyright © by Curt Hill
CSE 331 Subtyping slides created by Marty Stepp based on materials by M. Ernst, S. Reges, D. Notkin, R. Mercer, Wikipedia
ATS Application Programming: Java Programming
Inheritance "Question: What is the object oriented way of getting rich? Answer: Inheritance.“ “Inheritance is new code that reuses old code. Polymorphism.
Subtype Polymorphism, Subtyping vs
CSE 331 Software Design and Implementation
CSC 205 Programming II Lecture 2 Subclassing.
Modeling with Inheritance
lecture 08, OO Design Principle
Week 6 Object-Oriented Programming (2): Polymorphism
Effective Java: Classes and Interfaces
Advanced Java Programming
Software Design Lecture : 12.
Java – Inheritance.
Inheritance Inheritance is a fundamental Object Oriented concept
CMPE 135 Object-Oriented Analysis and Design March 21 Class Meeting
Lecture 11 Abstract Data Type
Chapter 9 Carrano Chapter 10 Small Java
Abstract Method & Abstract Classes
Chapter 8 Class Inheritance and Interfaces
CS 112 Programming 2 Lecture 02 Abstract Classes & Interfaces (2)
Chapter 11 Inheritance and Encapsulation and Polymorphism
Topics OOP Review Inheritance Review Abstract Classes
Chapter 8 - Design Strategies
ITE “A” GROUP 2 ENCAPSULATION.
CIS 110: Introduction to computer programming
Jim Fawcett CSE687 – Object Oriented Design Spring 2015
Presentation transcript:

Design Principles

Minimize Access of Member Encapsulate what varies Favor composition over inheritance Program to interface Liskov Substitution Principle Open-closed Principle

Abstraction “Abstraction arises from a recognition of similarities between certain objects, situations, or processes in the real world, and the decision to concentrate upon those similarities and to ignore for the time being the differences.” Tony Hoare “An abstraction denotes the essential characteristics of an object that distinguish it from all other kinds of objects and thus provide crisply defined conceptual boundaries, relative to the perspective of the viewer.” Grady Booch

Encapsulation “Encapsulation is the process of compartmentalizing the elements of an abstraction that constitute its structure and behavior; encapsulation serves to separate the contractual interface of an abstraction and its implementation.” Grady Booch “Encapsulation is a mechanism used to hide the data, internal structure, and implementation details of an object. All interaction with the object is through a public interface of operations.” Craig Larman

Minimize the Accessibility of Classes and Members Classes should be opaque Classes should not expose their internal implementation details Use getters and setters Compare public double speed; vs private double speed; public double getSpeed() { return(speed); } public void setSpeed(double newSpeed) { speed = newSpeed; }

Minimize the Accessibility of Classes and Members Classes should be opaque Classes should not expose their internal implementation details Use getters and setters Compare public double speed; vs private double speed; public double getSpeed() { return(speed); } public void setSpeed(double newSpeed) { speed = newSpeed; } Is this better? Why?

Advantages of minimizing accessibility Centralized checking of constraints Add useful side-effects (monitoring) Decouple internal representation from function: Improved encapsulation Reduced coupling of components

Favor Composition over Inheritance

Composition Method of reuse in which new functionality is obtained by creating an object composed of other objects New functionality obtained by delegating to objects being composed Sometimes called aggregation or containment Aggregation - when one object owns or is responsible for another object and both objects have identical lifetimes (GoF) Aggregation - when one object has a collection of objects that can exist on their own (UML) Containment - a special kind of composition in which the contained object is hidden from other objects and access to the contained object is only via the container object (Coad)

Advantages of Composition Contained objects are accessed by the containing class solely through their interfaces "Black-box" reuse, since internal details of contained objects are not visible Good encapsulation Fewer implementation dependencies Each class is focused on just one task (cohesion) The composition can be defined dynamically at run-time through objects acquiring references to other objects of the same type

Disadvantages of Composition Resulting systems tend to have more objects Interfaces must be carefully defined in order to use many different objects as composition blocks

Inheritance Method of reuse in which new functionality is obtained by extending the implementation of an existing object The generalization class (the superclass) explicitly captures the common attributes and methods The specialization class (the subclass) extends the implementation with additional attributes and methods

Advantages of Inheritance New implementation is easy, since most of it is inherited Easy to modify or extend the implementation being reused

Disadvantages of Inheritance Breaks encapsulation, since it exposes a subclass to implementation details of its superclass "White-box" reuse, since internal details of superclasses are often visible to subclasses Subclasses may have to be changed if the implementation of the superclass changes Implementations inherited from superclasses can not be changed at runtime

Example (from Effective Java by Bloch) Variant of HashSet that tracks number of insertions public class InstrumentedHashSet extends HashSet { private int addCount = 0; // The number of attempted element insertions public InstrumentedHashSet(Collection c) {super(c);} public InstrumentedHashSet(int initCap, float loadFactor) { super(initCap, loadFactor); } public boolean add(Object o) { addCount++; return super.add(o); } public boolean addAll(Collection c) { addCount += c.size(); return super.addAll(c); } public int getAddCount() { return addCount; }

Example (from Effective Java by Bloch) Variant of HashSet that tracks number of insertions public class InstrumentedHashSet extends HashSet { private int addCount = 0; // The number of attempted element insertions public InstrumentedHashSet(Collection c) {super(c);} public InstrumentedHashSet(int initCap, float loadFactor) { super(initCap, loadFactor); } public boolean add(Object o) { addCount++; return super.add(o); } public boolean addAll(Collection c) { addCount += c.size(); return super.addAll(c); } public int getAddCount() { return addCount; } Keep track of insertions Call super constructor

When we add, update the counter Example (from Effective Java by Bloch) Variant of HashSet that tracks number of insertions public class InstrumentedHashSet extends HashSet { private int addCount = 0; // The number of attempted element insertions public InstrumentedHashSet(Collection c) {super(c);} public InstrumentedHashSet(int initCap, float loadFactor) { super(initCap, loadFactor); } public boolean add(Object o) { addCount++; return super.add(o); } public boolean addAll(Collection c) { addCount += c.size(); return super.addAll(c); } public int getAddCount() { return addCount; } When we add, update the counter

Example: Test it! public static void main(String[] args) { InstrumentedHashSet s = new InstrumentedHashSet(); s.addAll(Arrays.asList(new String[] {"Snap","Crackle","Pop"})); System.out.println(s.getAddCount()); }

Example: Test it! public static void main(String[] args) { InstrumentedHashSet s = new InstrumentedHashSet(); s.addAll(Arrays.asList(new String[] {"Snap","Crackle","Pop"})); System.out.println(s.getAddCount()); } What’s the result?

Example: Test it! public static void main(String[] args) { InstrumentedHashSet s = new InstrumentedHashSet(); s.addAll(Arrays.asList(new String[] {"Snap","Crackle","Pop"})); System.out.println(s.getAddCount()); } RESULT: 6

Example: Test it! public static void main(String[] args) { InstrumentedHashSet s = new InstrumentedHashSet(); s.addAll(Arrays.asList(new String[] {"Snap","Crackle","Pop"})); System.out.println(s.getAddCount()); } The internal implementation of addAll() in the HashSet superclass invokes the add() method. First we add 3 to addCount in InstrumentedHashSet’s addAll(). Then we invoke HashSet’s addAll(). For each element, this addAll() invokes the add() method, which as overridden by InstrumentedHashSet adds one for each element.

Need to know the implementation details to get this right! Example: Test it! Need to know the implementation details to get this right! public static void main(String[] args) { InstrumentedHashSet s = new InstrumentedHashSet(); s.addAll(Arrays.asList(new String[] {"Snap","Crackle","Pop"})); System.out.println(s.getAddCount()); } The internal implementation of addAll() in the HashSet superclass invokes the add() method. First we add 3 to addCount in InstrumentedHashSet’s addAll(). Then we invoke HashSet’s addAll(). For each element, this addAll() invokes the add() method, which as overridden by InstrumentedHashSet adds one for each element.

Example: Composition Let’s write an InstrumentedSet class that is composed of a Set object. Our InstrumentedSet class will duplicate the Set interface, but all Set operations will actually be forwarded to the contained Set object. The contained Set object can be an object of any class that implements the Set interface (and not just a HashSet)

Favor Composition over Inheritance public class InstrumentedSet implements Set { private final Set s; private int addCount = 0; public InstrumentedSet(Set s) {this.s = s;} public boolean add(Object o) { addCount++; return s.add(o); } public boolean addAll(Collection c) { addCount += c.size(); return s.addAll(c); public int getAddCount() {return addCount;}

Forwarding methods public void clear() { s.clear(); } public boolean contains(Object o) { return s.contains(o); } public boolean isEmpty() { return s.isEmpty(); } public int size() { return s.size(); } public Iterator iterator() { return s.iterator(); } public boolean remove(Object o) { return s.remove(o); } public boolean containsAll(Collection c) { return s.containsAll(c); } public boolean removeAll(Collection c) { return s.removeAll(c); } public boolean retainAll(Collection c) { return s.retainAll(c); } public Object[] toArray() { return s.toArray(); } public Object[] toArray(Object[] a) { return s.toArray(a); } public boolean equals(Object o) { return s.equals(o); } public int hashCode() { return s.hashCode(); } public String toString() { return s.toString(); }

Coad's Rules: Use inheritance only when all of the following criteria are satisfied: A subclass expresses "is a special kind of" and not "is a role played by a" An instance of a subclass never needs to become an object of another class A subclass extends, rather than overrides or nullifies, the responsibilities of its superclass A subclass does not extend the capabilities of what is merely a utility class For a class in the actual Problem Domain, the subclass specializes a role, transaction or device

Program to an Interface, not an Implementation

Program to an Interface, not an Implementation Interfaces express types in a limited way An interface is the set of methods one object knows it can invoke on another object An object can have many interfaces Different objects can have the same type and the same object can have many different types An object is known by other objects only through its interface

Advantages: Clients are unaware of the specific class of the object they are using One object can be easily replaced by another Object connections need not be hardwired to an object of a specific class, thereby increasing flexibility Loosens coupling Increases likelihood of reuse Improves opportunities for composition since contained objects can be of any class that implements a specific interface

Open/Closed Principle Software should be Open for Extension, but Closed for Modification

Open/Closed Principle The Open-Closed Principle (OCP) says that we should attempt to design modules that never need to be changed To extend the behavior of the system, we add new code. We do not modify old code. Modules that conform to the OCP meet two criteria: Open For Extension - The behavior of the module can be extended to meet new requirements Closed For Modification - the source code of the module is not allowed to change How can we do this? Abstraction Polymorphism Inheritance Interfaces

Open/Closed Principle Consider the following method that totals the price of each part in the specified array of parts of some class: public double totalPrice(Part[] parts) { double total = 0.0; for (int i=0; i<parts.length; i++) { total += parts[i].getPrice(); } return total; If Part is a base class or an interface and polymorphism is being used, then this class can easily accommodate new types of parts without having to be modified! It conforms to the OCP

Open/Closed Principle Suppose the Accounting Department decrees that motherboard parts and memory parts should have a premium applied when figuring the total price. public double totalPrice(Part[] parts) { double total = 0.0; for (int i=0; i<parts.length; i++) { if (parts[i] instanceof Motherboard) total += (1.45 * parts[i].getPrice()); else if (parts[i] instanceof Memory) total += (1.27 * parts[i].getPrice()); else total += parts[i].getPrice(); } return total;

Open/Closed Principle Suppose the Accounting Department decrees that motherboard parts and memory parts should have a premium applied when figuring the total price. public double totalPrice(Part[] parts) { double total = 0.0; for (int i=0; i<parts.length; i++) { if (parts[i] instanceof Motherboard) total += (1.45 * parts[i].getPrice()); else if (parts[i] instanceof Memory) total += (1.27 * parts[i].getPrice()); else total += parts[i].getPrice(); } return total; Is this OK?

Open/Closed Principle Suppose the Accounting Department decrees that motherboard parts and memory parts should have a premium applied when figuring the total price. public double totalPrice(Part[] parts) { double total = 0.0; for (int i=0; i<parts.length; i++) { if (parts[i] instanceof Motherboard) total += (1.45 * parts[i].getPrice()); else if (parts[i] instanceof Memory) total += (1.27 * parts[i].getPrice()); else total += parts[i].getPrice(); } return total; Does not conform to OCP totalPrice() must be changed whenever Accounting changes pricing policy What could we do instead?

Open/Closed Principle A better idea is to have a PricePolicy class which can be used to provide different pricing policies: public class Part { private double price; private PricePolicy pricePolicy; public void setPricePolicy(PricePolicy pricePolicy) {this.pricePolicy = pricePolicy;} public void setPrice(double price) {this.price = price;} public double getPrice() {return pricePolicy.getPrice(price);} }

Open/Closed Principle /** * Class PricePolicy implements a given price policy. */ public class PricePolicy { private double factor; public PricePolicy (double factor) { this.factor = factor; } public double getPrice(double price) { return price * factor; }

Open/Closed Principle pricing policies can be set dynamically by changing the PricePolicy object /** * Class PricePolicy implements a given price policy. */ public class PricePolicy { private double factor; public PricePolicy (double factor) { this.factor = factor; } public double getPrice(double price) { return price * factor; }

Liskov Substitution Principle Functions that use References to Super Classes must be able to use Objects of sub-class types Barbara Liskov, Turing Award 2008