0% found this document useful (0 votes)
7 views30 pages

Software Design: Duplication, Coupling, Cohesion

The document discusses key principles of software design, focusing on the importance of maintaining code quality through concepts like duplication, coupling, and cohesion. It emphasizes the need for responsibility-driven design and refactoring to ensure code remains understandable and maintainable over time. The document concludes that good quality code avoids duplication, exhibits high cohesion and low coupling, and highlights the significance of coding style.

Uploaded by

retoha1696
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views30 pages

Software Design: Duplication, Coupling, Cohesion

The document discusses key principles of software design, focusing on the importance of maintaining code quality through concepts like duplication, coupling, and cohesion. It emphasizes the need for responsibility-driven design and refactoring to ensure code remains understandable and maintainable over time. The document concludes that good quality code avoids duplication, exhibits high cohesion and low coupling, and highlights the significance of coding style.

Uploaded by

retoha1696
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd

Comp1004: Building

Better Classes II
Software Design

Partly based on BlueJ Book – Chapter 7


Coming Up

• Duplication
• Coupling
• Cohesion
• Responsibility-driven design
• Refactoring
Software changes
• Software is not like a novel that is written once
and then remains unchanged.
• Software is extended, corrected, maintained,
ported, adapted…
• The work is done by different people over
time (often decades).
Change or die
• There are only two options for software:
– Either it is continuously maintained
– or it dies.

• Software that cannot be maintained will be thrown away.

• Three important concepts for quality of code:


– Duplication
– Coupling
– Cohesion
Duplication
public void getTotal(int[] array) {

int totalcost = 0;

for(int n : array){
totalcost += n;
}
return totalcost;
}

public void getTotalIncVAT(int[] array) {


int totalcost = 0;

for(int n : array){
totalcost += n;
}

totalcost = totalcost * 1.2;


return totalcost;
}
Duplication
public void getTotal(int[] array) {
Code Duplication is an
int totalcost = 0;
indicator of bad design

for(int n : array){
Makes maintenance harder
totalcost += n; and can lead to the
} introduction of errors
return totalcost;
}
What is a better solution?
public void getTotalIncVAT(int[] array) {
int totalcost = 0;

for(int n : array){
totalcost += n;
}

totalcost = totalcost * 1.2;


return totalcost;
}
Duplication
public void getTotal(int[] array) {
Code Duplication is an
int totalcost = 0;
indicator of bad design

for(int n : array){
Makes maintenance harder
totalcost += n; and can lead to the
} introduction of errors
return totalcost;
}
What is a better solution?
public void getTotalIncVAT(int[] array) {
int totalcost = getTotal(array); Use methods to write code
once and call many times
totalcost = totalcost * 1.2;
return totalcost;
}
Coupling
• Coupling refers to links between separate
units of a program.

• If two classes depend closely on many details


of each other, we say they are tightly coupled.

• We aim for loose coupling.


Loose coupling
• Loose coupling makes it possible to:
– understand one class without reading others;
– change one class without affecting others.
– Thus: improves maintainability.
Real World Examples
Are these tightly or loosely coupled systems?

Household Plumbing The Human Body


Real World Examples
Are these tightly or loosely coupled systems?

Loosely Coupled Tightly Coupled

Modular, each section is independent and Each part is linked in thousands of ways to
linked to the whole through a simple the whole. This creates excellent
interface. So it is easy to change one bit performance and is very efficient, but
without breaking the rest (within reason). makes it difficult to maintain

Household Plumbing The Human Body


Cohesion
• Cohesion refers to the the number and
diversity of tasks that a single unit is
responsible for.
• If each unit is responsible for one single
logical task, we say it has high cohesion.
• Cohesion applies to classes and methods.
• We aim for high cohesion.
High cohesion
• High cohesion makes it easier to:
– understand what a class or method does;
– use descriptive names;
– reuse classes or methods.

Cohesion of Methods Cohesion of Classes

A method should be responsible for Classes should represent one single,


one and only one well defined task. well defined entity.
Responsibility-driven design
• Question: where should we add a new
method (which class)?
• Each class should be responsible for
manipulating its own data.
• The class that owns the data should be
responsible for processing it.
• RDD leads to low coupling and high cohesion
Responsibility-driven design
• Question: where should we add a new
method (which class)?
• Each class should be responsible for
manipulating its own data.
• The class that owns the data should be
responsible for processing it. on
l ati
• RDD leads to low coupling. su
a p
n c
E
public class DogBooking {
protected String name;
protected String breed;
protected String ownersname;
protected Calendar startDate;
protected Calendar endDate;

//some code omitted

public void printInvoice() {


[Link](name + “, ” + breed);

int numDaysInMilliseconds = [Link](endDate);


int numDays = numDaysInMilliseconds / (1000 * 60 * 60 * 24);

[Link](“Nights in total: ” + numDays);


[Link](“Total cost: ” + getCost(numDays));
}
}
public class DogBooking {
protected String name; Cohesion of Methods
protected String breed;
protected String ownersname;
A method should be responsible for
protected Calendar startDate;
protected Calendar endDate;
one and only one well defined task.

//some code omitted


Is this method cohesive?
public void printInvoice() {
[Link](name + “, ” + breed);

int numDaysInMilliseconds = [Link](endDate);


int numDays = numDaysInMilliseconds / (1000 * 60 * 60 * 24);

[Link](“Nights in total: ” + numDays);


[Link](“Total cost: ” + getCost(numDays));
}
}
public class DogBooking {
protected String name; Cohesion of Methods
protected String breed;
protected String ownersname;
A method should be responsible for
protected Calendar startDate;
protected Calendar endDate;
one and only one well defined task.

//some code omitted


Is this method cohesive?
public void printInvoice() {
printDetails(); Arguably it does three
int numDays = getNumberOfDays();
things – so it would be
better to pull the other two
[Link](“Nights in total: ” + numDays);
out into separate methods
[Link](“Total cost: ” + getCost(numDays));
}

public void printDetails() {


[Link](name + “, ” + breed);
}

public int getNumberOfDays() {


int numDaysInMilliseconds = [Link](endDate);
return numDaysInMilliseconds / (1000 * 60 * 60 * 24);
}

}
public class DogBooking {
protected String name; Cohesion of Classes
protected String breed;
protected String ownersname;
Classes should represent one single,
protected Calendar startDate;
protected Calendar endDate;
well defined entity.

//some code omitted


Is this class cohesive?
public void printInvoice() {
printDetails();

int numDays = getNumberOfDays();

[Link](“Nights in total: ” + numDays);


[Link](“Total cost: ” + getCost(numDays));
}

public void printDetails() {


[Link](name + “, ” + breed);
}

public int getNumberOfDays() {


int numDaysInMilliseconds = [Link](endDate);
return numDaysInMilliseconds / (1000 * 60 * 60 * 24);
}

}
public class Dog {
protected String name; Cohesion of Classes
protected String breed;
protected String ownersname;
Classes should represent one single,
//some code omitted
well defined entity.

public void printDetails() {


[Link](name + “, ” + breed);
Is this class cohesive?
}
} Arguably it is better
public class Booking {
represented by two classes
protected Dog dog; – one to hold the details of
protected Calendar startDate;
the dog, the other the
protected Calendar endDate;
details of the booking
//some code omitted

public void printInvoice() {


[Link]();

int numDays = getNumberOfDays();

[Link](“Nights in total: ” + numDays);


[Link](“Total cost: ” + getCost(numDays));
}

public int getNumberOfDays() {


int numDaysInMilliseconds = [Link](endDate);
return numDaysInMilliseconds / (1000 * 60 * 60 * 24);
}
}
Localizing change
• One aim of reducing coupling and
responsibility-driven design is to localize
change.
• When a change is needed, as few classes as
possible should be affected.
Thinking ahead
public void switchOffElectrics() { When designing a class, we
//switch off all four lights
try to think what changes
Lights[] lights = getLights(); are likely to be made in the
future.
lights[0].switchOff();
lights[1].switchOff();
lights[2].switchOff(); We aim to make those
lights[3].switchOff();
changes easy
//setHeatingtoMinimum
HeatingControl hc = getHeatingControl(); What might we change
[Link](18);
here?
}
Thinking ahead
public void switchOffElectrics() { When designing a class, we
//switch off all lights
try to think what changes
Lights[] lights = getLights(); are likely to be made in the
future.
for(Light light : lights) {
[Link]();
} We aim to make those
//setHeatingtoMinimum
changes easy
HeatingControl hc = getHeatingControl();
[Link](18); What might we change
here?
}

Use a loop to switch off the


lights – now it doesn’t
matter how many we have
Thinking ahead
public void switchOffElectrics() { When designing a class, we
//switch off all lights
try to think what changes
Lights[] lights = getLights(); are likely to be made in the
future.
for(Light light : lights) {
[Link]();
} We aim to make those
//setHeatingtoMinimum
changes easy
HeatingControl hc = getHeatingControl();
[Link](getLowTemperature()); What might we change
here?
}

protected int getLowTemperature() { Use a loop to switch off the


//low is currently defined as 18
return 18; lights – now it doesn’t
} matter how many we have

Hide the low temperature


behind another method – in
case it changes in the future
Refactoring
• When classes are maintained, often code is
added.
• Classes and methods tend to become longer.
• Every now and then, classes and methods
should be refactored to maintain cohesion and
low coupling.
Refactoring and testing
• When refactoring code, separate the
refactoring from making other changes.
• First do the refactoring only, without changing
the functionality.
• Test before and after refactoring to ensure
that nothing was broken.
Design questions
• Common questions:
– How long should a class be?
– How long should a method be?

• Can now be answered in terms of cohesion


and coupling.
Design guidelines
• A method is too long if it does more then one
logical task.
• A class is too complex if it represents more
than one logical entity.

• Note: these are guidelines - they still leave


much open to the designer.
Summary
• Programs are continuously changed.
• It is important to make this change possible.
• Quality of code requires much more than just
performing correct at one time.
• Code must be understandable and
maintainable.
Summary
• Good quality code
– avoids duplication
– displays high cohesion, low coupling.
• Coding style (commenting, naming, layout,
etc.) is also important.
• There is a big difference in the amount of
work required to change poorly structured
and well structured code.

You might also like