CS3342 Lecture 7

Software Design Principles - SRP, ISP, LOD & Cohesion,Coupling

Single Responsibility Principle (SRP)

Just because you can, doesn't mean you should.

Example SPR:

The design violates SRP. Class Rectangle has two responsibilities.
1.Provide a mathematical model of the geometry of a rectangle in function area().
2.Render the rectangle on a graphical user interface (GUI) via draw().
 
Problem 1, consuming more time in linking and memory footprint. The .class files for the GUI have to be deployed to the target platform.
Problem 2, if any change to the GraphicalApplication may force changes in Rectangle and subsequently causing changes to ComputationalGeometryApplication, needs to rebuild, re-test and re-deploy.
Example SPR - Better Design:
Separate two responsibilities into multiple classes:

SRP Violation Example:

Interface Modem {
   public void dial(String No);
   public void hangup();
   public void send(char c);
   public char recv(); 
}

Two responsibilities in here:

1.Connection Management - dial() and hangup()
2.Data Communication – send() and recv()

Solution - Split into two interface:

Interface DataChannel {
   public void send(char c);
   public char recv(); 
}
Interface Connection {
    public void dial(String No);
    public void hangup();
}
Class Modem implements DataChannel, Connection {
   public void send(char c)  { …. }
   public char recv() { …. }
   public void dial(String No) { …. }
   public void hangup() { …. }
}

SRP Violation Example2:

The above class has 2 responsibilities
  1. serves info for sender/receiver.
  2. actual content of the email.
Extension of content may be a problem.
Create a new Content interface/class, To split the responsibilities, a more flexible design.
Extension of different contents change only in the Content class.

 

SRP - Summary:

  • Object Classes should have a single responsibility.(Single Purpose)
  • If you have a class that “doing two things”, split it into multiple classes. 
  • Separation of Concern. 
    • Never be more than one reason for a class to change. 
    • An important principle for future maintenance and upgrades

 


Interface Segregation Principle (ISP)

Client class should not be forced to depend upon interfaces that they do not use.

Avoid classes with too many responsibilities
Divide a large interface into a set of smaller interfaces. But make sure that each interface is self-contained.
ISP Example:

ISP Example2:

Violation:

Student can also Grade Assignments, NOT desirable.

Solution:

ISP Example3 - ATM System:

Violation:

Solution:

 

 

Law of Demeter (LoD)  - Principle of Least Knowledge

LoD is a specific case of Loose Coupling in OO
Resulting software being more: 1. Maintainable 2. Adaptable

Each unit should only have limited knowledge about other units: only about units “closely” related to the current unit.

“Each unit should only talk to its friends.” i.e. “Don’t talk to strangers.”
Example Lod:

A human (dog owner) should only order the dog to “walk”. e.g.In Human Object-> dog.walk()

NOT to tell how the dog should walk. e.g In Human Object -> dog.leftLeg.move(10); dog.RightLeg.move(10);… etc

Violation of LoD:

Violation:

  this.b.c.foo(10);   //A and B are friends, but A and C are not friends.

  this.p.q.bar(10);   //A and P are friends, but A and Q are not friends.

Not Violation:

  this.b.C_foo(10);   //A and B are friends, C_foo(10) is friends' method

  this.p.Q_bar(10);   //A and P are friends, Q_foo(10) is friends' method

 

Cohesion and Coupling

Understand Cohesion and Coupling (Measurement of Structural Ability)

Cohesion(內凝聚力) is the ability for a module to work independently from all other modules.
  • Each module represent a function, such as data entry, printing.
  • Should have a single entry and a single exit.
Coupling(耦合) is accomplished by using interface between modules that enables data to be passed from one module to another.
  • E.g. Variables Passing

 

Coupling(彼此耦合)

Good Design for OO programming - High Cohesion(+) and Low Coupling (-):

  • High Cohesion within modules focusing on what it should be doing
  • Low Coupling, low dependency on each other
Low Cohesion (does many actions and is not focused on what it should be doing)
Example Class Staff has
  • checkEmail()
  • sendEmail()
  • PrintLetter()
  • organizeWork()
High Cohesion (focused on what it should be doing)
Example Class Staff has
  • setSalary(newSalary)
  • setEmailAddress(newEmail)
  • setPersonalDetails(newDetails)

Criteria for Good Design

1.Low coupling between every two  packages or classes
  Coupling: There is a coupling from X to Y if changing X may lead to a change in Y.
    Coupling is reflected by the number of links an entity has and by the degree of interaction the entity has with other entities.
2.High cohesion within a package or class
  Cohesion is a measure of the degree to which an element contributes to a one and only one purpose.
    Cohesion is for the semantics (i.e., the meaning).

    Queue 1 us more meaningful

Intuition on Coupling

A package or a class can be considered as a component.
Highly coupled when there is a strong dependency.
Loosely coupled components have some dependency, but the interconnections among components are weak
Uncoupled components have no interconnections at all

Data Coupling, Stamp Coupling

Data coupling: Two components are data coupled if they communicate via a parameter.
  • E.g., use primitive data type or the object as a parameter, and use the data and object as a whole (e.g., treat it as an atomic unit).
  • setMoney (Money m) , getMoney() returns a Money object
Stamp coupling: if they communicate through a complex data structure, but both components do not use all fields of the data structure
  • E.g., Suppose that an object has three attributes. Component A only uses the first two attributes, Component B only uses the last two attributes, and Component C only uses the first and the third attributes.
  Example:
  
Control coupling: data (control flag(true/false)) from one component is used to control the direction of the execution in the other component
Common coupling(Gloabl variable): Two components are commonly coupled when both reference the same global data variable.
  • E.g., using a global variable (or log file or database) to transfer data between the modules. Difficult to track the relationships between components. It is a data-driven approach.
  • E.g., Class A directly updates the attribute foo of Class B, and class C directly reads the attribute foo from the Class B. i.e. needs to make attribute foo public (globally accessible), not desirable… 
  • Global variables in most of the cases, easy to use, but not a good idea..
Content coupling: if one module heavily depends on the internal working mechanism of another module. Therefore, changing the way the second module produces data (even the interface and the functionality are the same) will lead to changing the dependent module.
  • To duplicate similar function

 

  • E.g., clone code.

Types of Cohesion

A component is cohesive if all elements of the component are directed toward and essential for performing the same task.
7 forms of cohesion:

3 Good Types of Cohesion:

Functional cohesion 
  • all of the variables and functions of a class contribute to a single, well-defined task.
 
Sequential cohesion (Chained)  
  • The output of one component serves as the input of the next component. (i.e., all the steps are essential so that the whole computation can be taken place).
Communicational cohesion 
  • A set of components references the same input information or generate different parts of the same output.

Cohesion Example - A library member borrows many books:

  Version 2 has higher cohesion.

Association Entity - version 2:

 

 

 

 

 

posted @ 2018-03-26 11:49  Charonnnnn  阅读(320)  评论(0编辑  收藏  举报