FIT9131
Week 11
Programming Foundations FIT9131
Program design and quality Week 11
1
FIT9131
Week 11
Lecture outline
• Code quality
• Program design • Coupling
• Cohesion
• Responsibility-driven design
• Refactoring
• Running Java code directly using the SDK
2
FIT9131
Week 11
Code readability code quality
in relation to
3
•
• •
public void printTicket(int age, String type) {
if (age < 10)
System.out.println("Your ticket is $5.00");
else if (type.equals("concession")) System.out.println("Your ticket is $7.50"); System.out.println("Your ticket is $10");
System.out.println("Thank you"); }
what will be displayed on the screen when this method is called with the actual values of 8 and "normal" for the 2 parameters?
is the code correct?
is the code easy to read?
FIT9131
Week 11
• •
what will be printed if age is >= 10 AND type is “concession”? is the code correct?
Code formatting improved
public void printTicket(int age, String type) {
if (age < 10)
System.out.println("Your ticket is $5.00");
else
if (type.equals("concession"))
System.out.println("Your ticket is $7.50");
System.out.println("Your ticket is $10"); System.out.println("Thank you");
}
4
FIT9131
Week 11
logic error fixed
Better Code...
public void printTicket(int age, String type) {
if (age < 10)
System.out.println("Your ticket is $5.00");
else
if (type.equals("concession"))
System.out.println("Your ticket is $7.50");
else
System.out.println("Your ticket is $10"); System.out.println("Thank you");
}
5
• •
by simply formatting the code properly, we could identify logic errors more easily!
is the code easier to read now?
FIT9131
Week 11
Importance of good design
A software application must provide the required functionality.
However, it is also important that the software is designed in a way that facilitates:
• Error detection and fixing • Maintenance
• Enhancement
• Extension
There is a big difference in the amount of work required to change poorly structured and well structured code.
Poor design in a program is generally not noticeable simply by executing it!
6
FIT9131
Week 11
Software changes
• Software is not like a novel that is written once and then remains unchanged.
• Software is constantly being extended, corrected, maintained, ported, adapted ...
• The work is typically performed by different people over time (often years, or decades).
• Software that cannot be corrected, maintained, ported , adapted or extended will be discarded eventually.
7
FIT9131
Week 11
Example : World of
This example is in project Chapter08 from textbook. It illustrates some examples of bad coding designs.
Zuul
8
FIT9131
Week 11
World of
Zuul's
Room Layouts
Pub
Outside
Theatre
Lab
Office
9
5 rooms, connected via 4 doors (exits)
FIT9131
Week 11
Code quality indicators
Some common indicators of poor code quality are: • code duplication
• lack of encapsulation and information hiding (week 8)
• a small modification to functionality typically results in a number of other seemingly unrelated changes over multiple methods or classes
• large methods 10
FIT9131
Week 11
Code quality
Coding style (comments/documentations, naming, layout, etc.) is also important! Hence the need for a Coding Standard.
Related design concepts that we have discussed previously :
• Abstraction (week 3)
• Modularisation (week 3)
indicators
11
FIT9131
Week 11
Code quality indicators
Another two important design concepts for quality of code are:
• Coupling • Cohesion
Good quality code avoids duplications, displays high cohesion, low coupling.
12
FIT9131
Week 11
Coupling and Cohesion
Cohesion : each component (class or method) is a sensible logical unit that includes tasks that are related in some manner
• high cohesion is good!
• Eg. a method which does one logical task,
such as displayMenu()
Coupling : the connections between components • high coupling is bad!
• Eg. 2 methods which share a lot of common attributes
13
FIT9131
Week 11
Coupling
“Couples” are links/connections between separate units (eg. classes) of a program.
The term coupling is used to describe how closely connected 2 units are.
If two units depend closely on many internal details of each other, we say they are tightly coupled.
We aim for loose coupling - that means we want a system where each class is largely independent from other classes, and communicates with other classes only via a small/simple, well-defined interface. It is generally impossible to have no coupling at all.
14
FIT9131
Week 11
Loose coupling
Loose coupling makes it possible to:
• understand one class without reading others • change one class without affecting others
Loose coupling improves readability & maintainability.
Coupling may be explicit or implicit.
An example of explicit coupling is public access to fields. For example in the Room class, the exits have all been declared as public attributes – a typical indication of bad design.
15
FIT9131
Week 11
Example : Explicit coupling in
For instance, in Zuul there are a number of classes that make use of the exit information:
• TheRoomclassstorestheexits(withpublicaccess!)
• The Game class initialises and uses the exits in several
places
• exits are defined in createRoom method
• exits are displayed in printWelcome method
• exits are used to find the next room in goRoom method
Zuul
What would be involved in implementing a new exit direction (eg. up, or down)? How many classes will this affect?
16
FIT9131
Week 11
Using encapsulation to reduce coupling
Poor encapsulation is shown here by the public fields in the Room class. (Encapsulation guideline: hide information from view – public attributes violate this guideline)
Encapsulation reduces coupling and leads to a better design.
17
FIT9131
Week 11
Using encapsulation to reduce coupling
Can you think of a similar example in Week 9’s lab exercise (and the assignment)?
Solution:
• Change the public fields to private; and
• Provide public accessor and mutator methods for these fields.
• Now we are free to change the implementation of the exits in the Room class without worrying about how that will impact on other (client) classes – as long as the interface (the accessors/mutators) remains the same.
18
FIT9131
Week 11
Example : Implicit coupling in
Implicit coupling is where one class depends on the internal information of another, but the dependence is not necessarily obvious.
Eg :
Zuul
In the CommandWords class :
private static final String[] validCommands = {"go", "quit", "help“};
In the Game class :
private void printHelp() {
Implicit Coupling between these 2 classes!
(what if you change one part but forgot to change the other?)
System.out.println("You are lost. You are alone. You wander"); System.out.println("around at the university."); System.out.println();
System.out.println("Your command words are:"); System.out.println(" go quit help");
}
19
FIT9131
Week 11
Implicit coupling
In the example shown on the previous slide, if we decide to add some new command words, we will need to change the code in more than one place/class – but it is not immediately clear which classes actually need to be changed (without scanning through the code of the entire program)!
A solution to this implicit coupling problem is to add a method to the CommandWord class to display the command words. Since the CommandWord class is responsible for command words, it should really be responsible for printing command words.
Now any class which needs to print out a list of valid command words can simply ask the method in the CommandWord class to do it. The list of command words will always be correct and current. And there is only one class to modify when we need to change the command words.
20
FIT9131
Week 11
Improved
public class CommandWords
{
CommandWords
class
// a constant array that holds all valid command words
private static final String[] validCommands = {"go", "quit", "help"};
// ... Other methods not shown here ...
public void showAll()
{
for (String command: validCommands) System.out.print(command + " ");
System.out.println();
}
}
21
the command words are now found in only one place
this method can now be called wherever a list of valid commands need to be printed
FIT9131
Week 11
Cohesion
Cohesion refers to the number and diversity of tasks that a single “unit” is responsible for.
If a unit is responsible for many different tasks, we say this unit has low cohesion.
If each unit is responsible for one single logical task, we say it has high cohesion.
Cohesion applies to methods, classes and groups of classes.
We aim for high cohesion, that is, a system where each unit of code (method or class) is responsible for one or more highly-related tasks.
22
FIT9131
Week 11
High cohesion benefits
Two important ways in which high cohesion benefits a design – readability and reuse.
High cohesion makes it easier to:
• read and understand what a class or method does;
• use descriptive names for classes and methods;
• re-use the class in a different program;
• modify code – since the code responsible for a task is likely to be together in the same unit
High cohesion improves the reusability of classes or methods.
23
FIT9131
Week 11
Cohesion principles
Cohesion of methods:
A method should be responsible for one and only one well defined task. For example, the printWelcome and play methods of Game class in Zuul (the bad version).
Cohesion of classes:
Classes should represent one single, well defined entity. For example, the Room class in Zuul (the good version).
24
FIT9131
Week 11
Example of good cohesion
public void play() {
printWelcome();
// Enter the main command loop. Here we repeatedly read // commands and execute them until the game is over.
boolean finished = false;
while (!finished)
{
Command command = parser.getCommand();
finished = processCommand(command); }
System.out.println("Thank you for playing. Good bye."); }
25
We could have just repeated the entire code from the printWelcome() method in this play()methodhere. However,thiswould have reduced the cohesion of the play() method.
FIT9131
Week 11
Cohesion and Coupling
So in summary, the design aim is to achieve:
• Low (or Loose) Coupling AND
• High (or Strong) Cohesion
26
FIT9131
Week 11
Code duplication
Code duplication:
• makes maintenance harder,
• can lead to introduction of errors during maintenance.
The problem is that when one section of the code is changed, the programmer may forget to update the duplicated section somewhere else.
Code duplication is usually a symptom of bad cohesion.
27
FIT9131
Week 11
Example: Code duplication in Zuul
System.out.println("You are " + currentRoom.getDescription());
System.out.print("Exits: ");
if (currentRoom.northExit != null)
System.out.print("north "); if (currentRoom.eastExit != null)
System.out.print("east ");
if (currentRoom.southExit != null)
System.out.print("south "); if (currentRoom.westExit != null)
System.out.print("west ");
System.out.println();
28
This code appears in both the printWelcome and goRoom modules
FIT9131
Week 11
Solution: Code duplication
The easiest way to avoid code duplication is : • place the duplicated code into a method
• call the method in the code sections where the original duplicated code was situated
So now if a change is required, we only need to change it in one place, and all the other “affected” sections will see the change automatically.
29
FIT9131
Week 11
Responsibility
Responsibility-driven design is the process of designing classes by assigning well-defined responsibilities to each class.
Used to determine which class should implement which part of the application.
Responsibility-driven design leads to low coupling.
-
driven design
30
FIT9131
Week 11
31
Responsibility
Two principles:
• Each class should be responsible for manipulating its own data.
• The class that owns the data should be responsible for processing it.
-
driven design
Eg. In the bad Zuul design, the Room class holds information about a room,
therefore it should produce a description for a room. This is actually being done by the Game class at the moment. Bad design according to the principles above!
FIT9131
Week 11
Localising change
When designing a class, we try to think what changes are likely to be made in the future (ie. anticipate changes and extensions), eg. using an ArrayList versus a fixed-size array to hold data.
• can you think of such an example in your assignment?
We aim to make those changes easy.
An aim of using responsibility-driven design is to reduce coupling and thus localise change.
When a change is needed, as few classes as possible should be affected.
32
FIT9131 Week 11
Refactoring
During the lifetime of an application, often code is added or changed.
Classes and methods tend to grow larger in size over time. Every now and then, classes and methods should be
refactored to maintain high cohesion and low coupling.
Refactoring is the process of restructuring existing code to achieve a good design or maintain a good design when an application is modified or extended. For instance, classes/methods which have become too large can typically be split into smaller ones.
33
FIT9131
Week 11
Refactoring and testing
Important to separate the refactoring process from any other changes.
• First do the refactoring only, without changing the functionality.
• Test before and after refactoring to ensure that nothing was broken by the process.
• Then make any changes to functionality (if needed).
34
FIT9131
Week 11
Design questions
Common questions:
• How long should a class be?
• How long should a method be?
There are no quantitative answers to these questions. However, we can answer these questions in terms of cohesion and coupling.
35
FIT9131 Week 11
Design guidelines
A class is too complex if it represents more than one logical entity.
A method is too long if it does more then one logical task.
36
Note that these are just guidelines - they still leave much decision open to the designer.
FIT9131
Week 11
Using the Java SDK directly
37
The BlueJ environment makes it easy for you to concentrate on solving the problem you are interested in, without having to worry about details that are irrelevant to the problem.
BlueJ uses the Java SDK (Software Development Kit) to compile and run Java programs. The syntax error messages you see on the BlueJ screen come from the SDK.
FIT9131
Week 11
Using the Java SDK directly
For Microsoft Windows, the SDK runs from the Windows command line.
If using the SDK directly, we need an editor that produces text output (e.g. Notepad or Wordpad) to edit our Java code. Then we need to compile and run the code from a command-line prompt.
• to do this, we need to tell Java where to start the program; this is typically done via a special method named “main”.
38
FIT9131
Week 11
The
In a typical Java program, there needs to be a class method called main. This is where the processing starts. BlueJ automatically creates this main method for you, and you don’t see it. If you use the SDK directly, you have to write a main method yourself.
To run a Java program, the command java is used and the name of the class is used as a parameter, e.g:
java Game
The Java system then looks for a method in the class Game with
the following signature:
public static void main(String[] args)
39
main
method
FIT9131
Week 11
Example :
main
Method
public static void main(String[] args) {
Game myGame = new Game();
myGame.play(); }
(1) Creating a Game object
(2) Calling a method from the Game object
Can you see how BlueJ perform these 2 tasks for you?
In this example, the main method needs to run the play method of the Game class, so it first has to create an instance (myGame) of that class, and then ask it to invoke play. This code is inside the Game class itself.
40
FIT9131
Week 11
The Explanations :
method header
main
public — because this method has to be called from outside the class (by
the SDK). So it has to be a public method.
static — because Java needs to call this method before creating an instance
of the class. So it has to be a class method. void — because it doesn’t return anything. main — because that’s a tradition from C/C++.
String[] args — to allow for any optional parameters to be passed to the main method when it is called. Usually this array of Strings is empty (null). Bluej offers a default set of {} to indicate this null value.
41
public static void main(String[] args)
FIT9131
Week 11
Compiling/Running a Java program with the SDK
The following steps show how to compile and run a Java program under the Microsoft Windows operating system. For examples using other operating systems (eg. Linux, Mac OS, etc), please look up the relevant operating manuals.
When you use BlueJ to develop your java programs, BlueJ performs most of these steps for you.
42
FIT9131 Week 11
(1) Compiling with the SDK
The SDK compiler is called javac. To run the SDK compiler, type in at the Windows command prompt:
javac
Windows command prompt
c:\work\fit9131> javac Game.java
Each Java class must be in a file named exactly the same as the class name (including correct case), with a .java extension.
43
Eg :
FIT9131
Week 11
(2) Running a program with the SDK
44
Each class has to be compiled separately first. For each .java file, the compiler creates a .class file.
Then we use the Java interpreter to “execute” the .class file.
The SDK interpreter is called java. This is the program that actually runs your programs.
FIT9131
Week 11
(2) Running a program with the SDK
To run the program, type in at the Windows command prompt:
java
c:\work\fit9131>java Game Windows
command prompt
45
Note : just specify the filename (Game), not the file extension (.class or .java) – the java interpreter knows which file to process.
FIT9131
Week 11
46
SDK Summary
0) Create Java source code (.java files) with a text editor. Create a main() method in the class where processing is to start.
1) 2)
Compile the .java files with the Java Compiler (javac.exe)
Run the program with the Java Interpreter (java.exe)
FIT9131
Week 11
Assignment 2 Due Date Reminder
• don’t forget that this is due in Week 12
• make sure you submit on time, to avoid the late
penalty
• the interviews will be held after the submission deadline.
• practice explaining and modifying your code before attending your interview!
• think about any mistakes you made in Assignment 1
• check the FIT9131 website for a checklist of the materials to submit
47
FIT9131
Week 11
Assignment 2
Important :
•Only the Test Strategy for
the Tree class is required. •both positive and negative
tests are required
Test Strategy
48
FIT9131
Week 11
Assignment 2
• refer to the Week 7 lecture notes, to make sure you
understand the required format for this document.
• both positive and negative tests need to be documented – so you need to add simple validation code within your set/get methods and constructors.
Test Strategy
49