Introduction JAVA Language
Introduction JAVA Language
Domain
Technical Services
UI
UI::Swing UI::Web
Swing Web
Domain::Sales
Domain
Sales
Designing Systems with Layers
The essential ideas of using layers are simple:
Organize the large-scale logical structure of a system into
discrete layers of distinct, related responsibilities, with a clean,
cohesive separation of concerns such that the "lower" layers are
low-level and general services, and the higher layers are more
application specific.
Collaboration and coupling is from higher to lower layers; lower-
to-higher layer coupling is avoided.
Buschmann, F., Meunier, R., Rohnert, H., Sommerlad,
P., and Stal, M. 1996. Pattern-Oriented Software
Architecture: A System of Patterns, Wiley.
Problems Addressed by the Layers
Pattern
The problems addressed by the Layers Pattern include
the following:
Source code changes are rippling throughout the system many
parts of the systems are highly coupled.
Application logic is intertwined with the user interface, so it
cannot be reused with a different interface or distributed to
another processing node.
Potentially general technical services or business logic is
intertwined with more application-specific logic, so it cannot be
reused, distributed to another node, or easily replaced with a
different implementation.
There is high coupling across different areas of concern. It is
thus difficult to divide the work along clear boundaries for
different developers.
GUI windows
reports UI
speech interface (AKA Presentation, View)
HTML, XML, XSLT, JSP, Javascript, ...
more
app
handles presentation layer requests specific
workflow Application
session state (AKA Workflow, Process,
dependency
window/page transitions Mediation, App Controller)
consolidation/transformation of disparate
data for presentation
Sale
A Payment in the Domain Model Payment 1
1 Pays-for
is a concept, but a Payment in date
the Design Model is a software amount
time
class. They are not the same
thing, but the former inspired the
inspires
naming and definition of the
objects
latter.
and
names in
This reduces the representational
gap.
Sale
This is one of the big ideas in Payment
object technology. 1 1 date: Date
Pays-for
amount: Money startTime: Time
Domain
Vertical Layers
Technical Services
Horizontal Partitions
Model-View Separation Principle
This principle has at least two parts:
Do not connect or couple non-UI objects directly to UI objects.
For example, don't let a Sale software object (a non-UI "domain"
object) have a reference to a Java Swing JFrame window object.
Why? Because the windows are related to a particular
application, while (ideally) the non-windowing objects may be
reused in new applications or attached to a new interface.
Do not put application logic (such as a tax calculation) in the UI
object methods. UI objects should only initialize UI elements,
receive UI events (such as a mouse click on a button), and
delegate requests for application logic on to non-UI objects (such
as domain objects).
Model = Domain Layer
View = User Interface Layer
Benefits of Model-View Separation
Supports cohesive model definitions that focus on the domain
processes, rather than on user interfaces.
Allows separate development of the model and user interface layers.
Minimizes the impact of requirements changes in the interface upon
the domain layer.
Allows new views to be easily connected to an existing domain
layer, without affecting the domain layer.
Allows multiple simultaneous views on the same model object, such
as both a tabular and business chart view of sales information.
Allows execution of the model layer independent of the user
interface layer, such as in a message-processing or batch-mode
system.
Allows easy porting of the model layer to another user interface
framework.
Connection Between SSDs,
System Operations and Layers
In a well-designed layered architecture,
the UI layer objects will forward or
delegate the requests from the UI layer
(system operations) onto the domain layer
for handling.
The messages sent from the UI layer to
the domain layer will be the messages
illustrated on the SSDs, such as enterItem.
Connection Between SSDs, System
Operations and Layers (cont.)
UI
Swing makeNewSale()
:System enterItem()
: Cashier ProcessSale endSale()
...
Frame
makeNewSale()
: Cashier
enterItem(id, quantity)
makeNewSale()
description, total enterItem()
endSale()
Domain
endSale()
... Register
makeNewSale()
enterItem()
...
+ controlVolume()
CryingObject
Class Dependencies on
Interfaces
A class can realize more
that one interfaces. Baby
Speaker
Also classes can depend on + controlVolume()
different interfaces provided + takePicture()
CryingObject
by the same class.
In the figure, class Baby
Camera
provides two interfaces:
CryingObject and
CuteObject. Class Speaker CuteObject
depends on CryingObject,
while class Camera
depends on CuteObject
Dependency is indicated
with a dashed arrow from
the client of the dependency
to the source of the
dependency
Advantages of Using Interfaces
Partitioning operations of a class to separate interfaces,
and the controlled way that other classes depend only on
selected interfaces, is one of the fundamental techniques
that can be used to manage the complexity of modern
software systems.
The basic reason for that, is that since a class only uses
a well defined subset of operations of a provider class
(those provided by the specific interfaces that it uses),
the provider class implementation can change as long as
the interface and the semantics of operation usage
(operation contracts) remains stable.
Example Using Interfaces
In the figure a class Person
implements the Java
Comparable interface. <<Interface>>
PriorityQueue, another Java Comparable PriorityQueue
Inserting Persons in the Queue
public static void main(String[] args) {
//A priority queue of Persons
PriorityQueue<Person> pq = new PriorityQueue<Person>();
//Inserting three persons in the queue
Person p3 = new Person(Natalia", 39);
Person p1 = new Person(George", 39);
Person p2 = new Person(Anastasia", 2);
pq.offer(p1);
pq.offer(p2); The result of the program
pq.offer(p3); execution is:
//Displaying the objects in the queue Age: 2, Name: Anastasia
Iterator<Person> i = pq.iterator(); Age: 39, Name: George
while (i.hasNext()) { Age: 39, Name: Natalia
Person p = i.next();
System.out.println(p);
}
}
Template (or Parametric) Classes
Sometimes we might want to define a class in which a
type of its properties will be a parameter of the class.
A classic example of this, is different kinds of container
classes, such as lists, sets and queues.
For example, if we were defining a priority queue, we
would probably like to do it without committing to the
specific type of elements that will be inserted in the
queue.
Advantages of doing so include the following:
Reuse of the same container class with elements of different
types
Strong type checking during compilation
UML Notation for Template
Classes
UML notation for template
classes is a small dashed
rectangle on the top left
corner of the class box, T
where we put the
parameters of the class. N:int
If the data type of a Array
parameter is omitted, it is
considered as a data type - elements[1..N] : T
of the system or the
programming language that + add(element : T)
will be used. If this is not the
case then we must write the
data type.
Bound Elements
Template class cant be used for the creation of
object instances. The parameters of the
template class, must be bound first to specific
data types and values, in order to become
concrete classes from which objects can be
created.
We cant create, for example, an array of objects
of type T. You have to create an array with
elements of a specific type (e.g. Person). These
concrete classes are called bound elements.
UML Bound Element Notation
Named
Bound
T
Unnamed Element N:int
Bound Array
Element - elements[1..N] : T
+ add(element : T)
PersonArray
- elements[1..50] : Person
Array<Person,50>
+ add()
() ()
Aggregation
Aggregation is an
association of a class with
another class that is a part
of the first: a whole-part
relationship.
Aggregation has only one
additional constraint
compared to a casual
association: the cyclic
association of the part back
to the whole is disallowed.
Aggregation is depicted with
a white diamond on the side
of the whole. .
Martin Fowler
Composition
Composition is a much stronger
whole-part relationship than
aggregation, with two additional
semantic elements
The whole contains its parts
exclusively (no sharing)
There is a life-and-death relationship
between the whole and its parts
(parts are created after the whole has
been created and are destroyed with
it).
UML symbol for the composition
association is a black diamond on
the whole side.
Qualified Associations
A qualified association uses a qualifier in one side of the
association, to determine the objects participating in this
association, to the other side.
In the figure the object Student is the qualifier and for
each student there are 0 or 1 lines in the Class Register.
We call the association between the Class Register and
its Lines a qualified association, with the qualifier being
objects of type Student.
-
:
0..1
Object Diagrams
An object or instance diagram, is a
snapshot of the system at some particular
moment, in which we depict the objects as
well as the links between them.
It is an example of the arrangement of
objects during runtime.
Theterm Object Diagram is not an official
term of the UML, but it is widely used.
Object
: DrawingArea line : Line
Diagram
Example group : Group circle : Circle
line2 : Line
Line Circle Group
()
Dependencies
Dependencies are depicted with dashed arrows
connecting a classifier from which they start and is called
the client of the dependency, with another classifier
called the source of the dependency.
If the source changes then this might cause changes to
the client, which depends on the source.
There are several predefined types of dependencies in
UML. If, for example, the classifiers are packages, and
we want to say that the client imports the source, we use
the import dependency instead of the more general
use dependency. If the client is a class calling a
method on the source, we use a call dependency.
Dependencies ARE NOT transitive.
Dependency Example
Assignment
Class Course depends on
Student, because it calls + getMark() : double
the getName method -assignments *
CourseRecord
Course -courseRecords
+ average() : double
+ getBestName() : String *
+ getStudent() : Student
: Secretary
* [ assignments] getMark( )
mark
average
s:=getStudent( )
name:=getName( )
Remarks on Sequence
Diagrams (1)
Sequence diagram does not depict the logic of
an operation (its algorithm)
Activation frames are important since they depict
the depict program flow from object to object,
with method call executions included in other
executing methods.
Each object calling a method in another object,
must be linked to that other object, either
permanently (with an association of the
respective class on the class diagram), or have
a transient relationship (e.g. the called object
might be a local variable or parameter)
Remarks on Sequence
Diagrams (2)
Operations being called on the different objects,
must be operations of the respective object
classes of the class diagram.
In relation to the previous comment, we must
say that assigning responsibilities to objects is a
key issue in object-oriented design.
We will discuss later some empirical rules for object
responsibility assignment called GRASP (General
Responsibility Assignment Software Patterns) .
Object Creation Notation
The creation of a new
object is depicted with UML : Course
a message being sent
to the created object, new(student, course) newRecord :
CourseRecord
that ends on the box
setStudent(student)
of the new object
being created.
Object Termination
Object termination is
depicted with an at the
end of its lifeline. UML : Course :Database record :
CourseRecord
If the termination of the
object is caused by storeRecord(record : CourseRecord)
another object, we can
show this with a signal destroy
sent by this other object
and that ends to the
symbol.
Self-call
When an object calls a
method on itself, this is a:A b:B c:C
depicted with a call that
starts and ends on the * [ b] foo( )
same object.
The activation frame of func1( )
the self-call in this case,
is contained entirely on func2( )
1. getBestName( )
1.3. name:=getName( )
1.1. *[ course record] average( )
programming
: Course
1.1.2. average
1.2. s:=getStudent( )
:
bestRec : CourseRecord
: Student CourseRecord
1.1.1.1. mark
: Assignment
State Diagram
A state diagram shows the dynamic behaviour of the
objects of a class and the way that their state is
changing as a reaction to events.
State diagrams are typically used to model the behaviour
of the instances of one class.
We dont usually draw state diagrams for all the classes
of a system. We only use them for these classes that
have a very dynamic behaviour. State diagrams help on
clarifying this behaviour.
State Diagram Example
Set Time
+ pressed / hrs++
switchOn / hrs=0, mins=0
Set Minutes
- pressed / mins--
+ pressed / mins++
Start and End States
You can use a filled circle
pseudo-state to depict the
start state, and a filled
circle included in an
empty circle for the end birth
state.
In the figure we can see
the not-so interesting life Living
of a human object (we
have omitted many
details of the composite
state living!)
death
Concurrent states
In some cases we want to show concurrent state diagrams,
to which an object is in two or more states at the same
time.
For this we can split one state in two or more parts with a
dashed line, and show the concurrent parts in these two
different segments.