Introduction to Object Oriented Programming, 3rd Ed

Timothy A. Budd

Chapter 23

Object interconnections

Outline

  1. Roadmap
  2. Connections -- The Bane of Large Scale Programming
  3. Visibility
  4. Dependency
  5. Coupling and Cohesion
    1. Varieties of Coupling
      1. Internal Data Coupling
      2. Global Data Coupling
      3. Control, or Sequence Coupling
      4. Component Coupling
      5. Parameter Coupling
      6. Subclass Coupling
    2. Varieties of Cohesion
  6. Limiting Coupling - the Law of Demeter
    1. Rewritten in Terms of Messages
    2. What is Rules Out
  7. Class-Level versus Object-Level Visibility
  8. Active Values
  9. Public, Subclass ans Private Faces
  10. Control of Visibility
    1. Friends in C++
    2. Inner classes
    3. Private Inheritance in C++
    4. name Spaces, Packages or Units
  11. Intentional Dependency
  12. Chapter Summary

Other Material

Intro OOP, Chapter 23, Outline

Roadmap

In this chapter we move up a level of abstraction, and consider collections of objects working together.

Our focus will be on how objects are connected to each other, and how one can make those connections as loose as possible.

Our primary tool for analyzing connectednesss will be the concepts of visibility and dependency.

Intro OOP, Chapter 23, Slide 01

Connections - The Bane of Large Scale Programming

Difficulties in developing large scale programs are often not so much a matter of algorithmic complexity as they are of communication complexity.

If several programmers are working together on a project, need to control the amount of information one programmer must have about the code being developed by a second programmer.

Intro OOP, Chapter 23, Slide 02

Visibility

Visibility is an attribute of names.

Intro OOP, Chapter 23, Slide 03

Dependency

Dependency describes the degree to which one software component relies on another component to perform its responsibilities.

A high degree of dependency obviously limits code reuse - moving one component to a new project.

Intro OOP, Chapter 23, Slide 04

Coupling and Cohesion

Ideas from the Software Engineering Community, pre-dating OOP.

Intro OOP, Chapter 23, Slide 05

Varieties of Coupling

Arranged from Bad to Better

Intro OOP, Chapter 23, Slide 06

Internal Data Coupling

class  SneekyModifier {
public:
  void sneeky () {
    // change my friends name		
    myFriend->name = "Lucy";
  }
  Person * myFriend;
};

class Person {
public:
  Person () { 
    name = "Larry";
  }
  string name;
};  

This is bad because it makes it difficult to understand a single class in isolation.

Can be mitigated by always making your data areas private or protected, and not exposing pointers to these areas.

Intro OOP, Chapter 23, Slide 07

Global Data Coupling


		double todaysDow;

class One {
public:
  void setDow () {
    todaysDow = 9473;		
  }
};

class Two {
public:
  void printDow () {
    cout << "Today the Dow hit "
      << todaysDow;
  }
};

Two or more classes that interact through a common global variable. Again, makes it difficult to understand a single class in insolation.

Can be mitigated by making a class that ``manages'' the global area, thereby reducing global coupling to component coupling.

Intro OOP, Chapter 23, Slide 08

Control, or Sequence Coupling

This occurs when objects are linked by the fact that one must be manipulated before the other, but otherwise they have no connection.

Again, makes it difficult to understand a class in isolation.

Can be mitagated by making a controller class, that clearly indicates the sequence of operations.

class MyClass {
public:
	doStuff () {
		doFirst();
		doSecond();
		doThird();
	}

protected:
	doFirst() { ... }
	doSecond() { ... }
	doThird() { ... }
}
Intro OOP, Chapter 23, Slide 09

Component Coupling

Occurs when one class holds an instance of another class.
class Set {
	...
private:
	List data;
}
Ideally, connection is one way. Held component has no knowledge or holder.

This is a very weak and benign connection. (Weak is good, remember).

Intro OOP, Chapter 23, Slide 10

Parameter Coupling

Parameter coupling occurs when one object knows of another only through being passed as a parameter or a return value.

Another very weak (and therefore good) type of coupling.

class MyClass {
public:
	void doSomething (Set aSet) {
		...
	}
}
Intro OOP, Chapter 23, Slide 11

Subclass Coupling

Subclass coupling describes the relationship between a parent class and a child class.

Ideally the parent has no strong connection to the child, so the connection is one way. Can understand the parent in isolation from the child.

class Parent {
	...
}

class Child extends Parent {
	...
}
A very weak form of coupling. Which makes it a good design choice.
Intro OOP, Chapter 23, Slide 12

Varieties of Cohesion

Also arranged from bad to better:

Intro OOP, Chapter 23, Slide 13

Limiting Coupling - the Law of Demeter

The law of demeter is an attempt to limit the way in which one component can interact with another component.

Law of Demter. In any Method M attached to a class C, only methods defined by the following classes may be used:
1.
The instance variable classes of C.

2.
The argument classes of method M (including C); note that global objects or objects created inside the method M are considered arguments to M.
Intro OOP, Chapter 23, Slide 14

Named for the Demeter project at Northeaster University.

Rewritten in terms of messages

Law of Demeter (weak form). Inside a method, it is only permitted to access or send messages to the following objects:

1.
The arguments associated with the method being executed (including the self object).

2.
Instance variables for the receiver of the method.

3.
Global variables.

4.
Temporary variables created inside the method.
Intro OOP, Chapter 23, Slide 15

The strong form eliminates global variables and inherited data fields.

What is ruled out

Basically, what is ruled out by the law of demeter is one object going in and directly manipulating the internal data values of another object.

Instead, all access to data values in another component should be made through procedures - thereby reducing data coupling to the weaker parameter coupling.

Intro OOP, Chapter 23, Slide 16

Class-Level versus Object-Level Visibility

Here is another interesting way that object-oriented languages have chosen to differ from each other.

Question: Are sisters and brothers allowed to look at each others private data fields?

An answer of YES is class-level visibility (C++ and Java) and answer of NO is object-level visibiity.

Intro OOP, Chapter 23, Slide 17

Active Values

The creation of active values is a good illustration of why parameter coupling is better than direct manipulation.

Suppose we have an existing program and we just want to observe a data value - see when it gets set and changed.

Solution - create a new subclass that just changes those methods that set or read the data value.
@interface Reactor : Object
{ ...
	double heat; ...
}
- (void)  setHeat: (double) newValue;	
- (double) getHeat;
@end

@implementation GraphicalReactor : Reactor
- (void) setHeat: (double) newValue
	{
		/* code necessary to */ 
		/* update gauge */
		[ super setHeat: newValue ];
	}
@end

Can add new functionality simply by replacing an object with an instance of a subclass; making no change to the original class.

Intro OOP, Chapter 23, Slide 18

Public, Subclass and Private Faces

We have several times noted that object have a public and private face - inheritance introduces a third alternative, the subclass face.

There are two types of clients for the class developer. These are user clients (those who use an instance of the class), and subclass clients (those who will subclass from the class).
Intro OOP, Chapter 23, Slide 19

Control of Visibility

The public/protected/private modifiers are the primary way to control visibility in most OO languages, the there are other mechanisms as well.
Intro OOP, Chapter 23, Slide 20

Friends in C++

In C++ a friend (class or method) is allowed access to all parts of a class.
class Complex { 
public: 
	Complex(double, double); 
	friend double abs(Complex&);
private: 
	double rp; 
	double ip; 
};

double abs(Complex& x)
{ 	return sqrt(x.rp * x.rp + x.ip * x.ip); }
Friendship is something that is given away, not something that is taken.
Intro OOP, Chapter 23, Slide 21

Inner Classes

Inner classes in Java and, to a lesser extent, nested classes in C++ and C# are allowed to access the data areas in the surrounding class.
class AcontainerClass {
	...
		// return an enumerator
	public Enumeration elements() 
		{ return new MyEnumeration(); }
	...
		// inner class is allowed to see
		// all aspects of surrounding class
	private class MyEnumeration implements Enumeration {
		...
		public boolean hasMoreElements () { ... }
		public Object nextElement() { ... }
	}
}
Uses a lot for event listeners in Java, among other things.
Intro OOP, Chapter 23, Slide 22

Private Inheritance in C++

In a public inheritance the public features of a parent become public features of a child.

In a private inheritance, the public and protected features of the parent do not filter through the child; and only the public features of the child are visible.

Intro OOP, Chapter 23, Slide 23

Name Spaces, Packages or Units

Names Spaces (in C++), Packages (Java) or Units (Delphi and Object Pascal) give the programmer another way to encapsulate names, and release only those names that are necessary.
package foo;
	public class bar { // will be visible
		...
	}

	class baz { // will not be visible outside package
		...
	}
Intro OOP, Chapter 23, Slide 24

Intentional Dependency

Sometimes want code to depend upon another class.

Sometimes want this even if the dependee doesn't know the dependant. (example, a model and its display).

Can be managed by having a separate ``dependancy manager''. When an object changes, it tells the manager ``notify my depedants''.

Intro OOP, Chapter 23, Slide 25

Chapter Summary

In this chapter we have examined a variety of topics related to dependency
Intro OOP, Chapter 23, Slide 26