Good OO design calls for LOOSE coupling and HIGH cohesion.
Coupling is the degree to which two classes 'know about each other'.
Cohesion is the purpose of the class. Is it well focused?
Coupling
Close coupling causes issues for code maintenance.
Enhancement or bug fixes to a class can be made without impacting the interface it presents.
Assumption is that changes will not impact anywhere else, why should it the interface has not changed.
A close coupled class uses part of the code changed, the alteration has an undetected impact!
Close coupling limits code reuse.
Cohesion
A class with high cohesion has a well defined purpose.
Classes designed with high cohesion are
Easier to maintain.
Less likely to require frequent changes.
Easier to reuse in multiple projects / applications.
Tend to be simpler to follow for other developers.
Generally have a well defined interface.
High Cohesion Loose Coupling
Remember when designing a class:
Define the purpose and don't let that creep.
Keep the inner functions of the class private.
Think about how you want other classes to interact with this class and define its interface accordingly.
Ask yourself, how easy would this class be to reuse in another project?
Structure we've seen
Blocks
Exception handling
Methods
Classes
Packages
Others we haven't: threads, parallelisation, other programs
Getting processor time
Usually a program will take over the processor once and run through the code a line at a time in one go.
However, you can force the processor to split up and run several copies of the same bit of code.
Each runs in its own processor "thread" of execution.
For example, you might want a web server to have one thread for each person accessing files so you can send the right file back to the right person, even though lots of requests are being made simultaneously.
Threads
Implement java.lang.Runnable interface and make a Thread object inside the class.
Extend java.lang.Thread class - this implements Runnable.
Either way you need a Runnable object and a Thread object
You need to call the Thread's start() method. This will look in the Runnable object for a run() method.
synchronized
The synchronized keyword stops more than one Thread / method at a time using the code.
Can be applied to methods and blocks.
The latter means you can synchronize object methods, even if you didn't write the class.
Split up a program so it runs on multiple computers.
For example, each computer does the calculation for a different geographical area.
Starting other programs
The environment the program is running in is encapsulated by a java.lang.Runtime object.
The current Runtime can be got with a static method.
Runtime rt = Runtime.getRuntime();
Runtime has methods to:
Deal with the computer memory.
Interact with the JVM interpreter
Run other programs.
Starting other programs
Other programs can be run by the JVM. They are encapsulated in a java.lang.Process object.
These can be got using the current Runtime.
Process processObject =
runtimeObject.exec("programlocation");
If the OS knows where a program is (i.e. it's in the PATH), we can just use a name.
Also a version of exec that takes in this and an array of arguments, as if the program was running at the command line.
Interacting
Once started you can use Process methods to drive the programs.
Reading from Processes... processObject.getInputStream()
Writing to Processes... processObject.getOutputStream()
Stopping Processes... processObject.destroy()
Structure we've seen
Blocks
Exception handling
Methods
Classes
Packages
Threads / Parallelisation
Other programs
Where do we get advice?
Patterns
"Patterns" are standard ways of solving a software problem that people come across again and again. They anen't specific to Java, or any other language.
They save us having to reinvent solutions.
The most influential book in the field was "Design Patterns - Elements of Reusable Software" by the "Gang of Four" Gamma, Helm, Johnson and Vlissides (1995).
The Gang of Four Patterns
They gave 23 patterns with C examples.
Creational Patterns - classes to make stuff:
The Factory, Abstract Factory, Singleton, Builder, and Prototype.
Structural Patterns - software architecture:
The Adapter, Bridge,Composite, Decorator, Facade, Flyweight and Proxy.
Behavioural Patterns - which classes do what:
The Chain of Responsibility, Command, Interpreter, Iterator, Mediator, Memento, Observer, State, Strategy, Template, and Visitor.
Patterns we've seen
Observer : Listeners.
Model-View-Controller: Swing.
Adapter Pattern: AWT.
Iterator: Enumerations.
Why Use Patterns?
Industry standard methods of doing something, therefore other programmers will understand your code.
They encapsulate solutions so you can get on with more tricky things.
They'll give you a deeper understanding of why Java is the way it is.
They're the advice of top experts with years of experience - they'll teach you a lot about good Object Orientated software design.
Book
Head First Design Patterns
Summary
Good Object Orientated code structure encourages robust and reusable software.
Read up on patterns: they'll teach you about good program style, and help solve major issues.