Upload
keona
View
58
Download
0
Embed Size (px)
DESCRIPTION
Object Design Basics. Java’s constructs for Objects. Interfaces Abstract classes Classes Subclasses Inner classes Anonymous classes. Nested classes. Static member classes. Non-static member classes. Anonymous classes. Local classes. Inner classes. Which member class to use. - PowerPoint PPT Presentation
Citation preview
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
1
Object Design Basics
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
2
Java’s constructs for Objects
• Interfaces
• Abstract classes
• Classes
• Subclasses
• Inner classes
• Anonymous classes
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
3
Nested classes
• Static member classes.
• Non-static member classes.
• Anonymous classes.
• Local classes.Inner classes
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
4
Which member class to use
• If a nested class needs to be visible outside of a single method, or its too long inside of the method, use a private member class.
• If each instance of the member class needs a reference to its enclosing instance, make it private non-static class.
• Otherwise make it static. • Use anonymous classes for those one-time-use
classes.
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
5
Exceptions
• Built-in
• User defined
• Use of finally clause
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
6
try {int i = 0;while(true) {
a[i++].f();}
}catch(ArrayIndexOutOfBoundsException e){}
Use exceptions only for exceptional conditions!!!
Do not use them for control flow of normal situations.
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
7
finally
try{…
}catch( ….) {
…}catch( ….) {
…} …finally { ….}
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
8
finally
• Code in finally is executes after try terminates either normally, abnormally or via return or break.
• Commonly use to release resources held by the object, I.e. to tell the garbage collector about an unused object.
• But: there is no guarantee that those statements will get executed promptly.
• So: – Nothing time critical should be done in them.– Never depend on a finalizer to update critical persistent
state.– Even better: Do not rely on finally clause.
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
9
finally
• What to do:– Provide an explicit termination method and require
clients to invoke it when needed resources are not longer needed.
– This method records that object is no longer valid, so if any other method in the instance gets invoked an IllegalStateException should be thrown.
– The method will invocation be the only line in the body of finally.
• It may be invoke later, rather than never at all.
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
10
Exception use
• Use checked exceptions for conditions for which the caller can reasonably be expected to recover.
• An API with a checked exception is telling the user that user is expected to recover from the condition that throws the exception. User can disregard it, but it is a poor tactic.
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
11
Exception use
• Use run-time exceptions to indicate programming errors.
• User is not expected to recover from these. • The largest percentage of these errors are
pre-condition violations.• Runtime exceptions are expected to appear
and be resolved during program development.
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
12
Exception use
• Favor use of standard Java exceptions– IllegalArgumentException
– IllegalStateException
– NullPointerException
– IndexOutOfBoundsException
– ConcurrentModificationException
– UnsupportedOperationException
– ArithmeticException
– NumerFormatException
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
13
Exception use
• Avoid confusion by allowing an exception to be passed on to higher levels, where the exception might not make reasonable sense
• An abstraction should catch a low-level exception and in its place throw an exception that is explainable in terms of the abstraction.
• Example: the add method to a bounded queue implemented using an array, can throw an IndexOutOfBoundsException. This does not make much sense for the client of the queue, as he is not expected to know the implementation choice in general. So the add method should catch the exception and throw it as FullQueueException.
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
14
Documenting exception
• Always declare checked exceptions individually, and document precisely the conditions under which each one is thrown using the Javadoc @throws tag.
• Document as well those exceptions which are RunTimeExceptions.
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
15
Exceptions are objects!
• Any checked exception should contain all the data, along with its queries, that caused the exception.
• Since we expect the caller to possibly recover from it, having that information will help the course of action to take.
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
16
Exception’s string message
• All RuntimeExceptions are expected to produce a system crash which will produce the exception string that caused the crash.
• Make sure that strings contains all the information needed to be able to understand what happens of what was possibly expected.
• Simple example: an IndexOutOfBoundsException should produce a message that states the lower bound, the upper bound of the array, along with the index value that caused the exception.
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
17
Strive for failure atomicity
• Generally speaking: a failed method should strive to leave the object in the original state prior to invocation.
• From the point of view of the client: a method get all done, or nothing gets done!
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
18
How to accomplish failure atomicity:making the object remain consistent.
• Get if for free if your object is immutable.• For mutable objects:
– Check conditions (parameters) before making changes.– Order algorithm so that the part that may fail occurs
before the part that make changes.– Use temporary objects to perform the algorithm, and
replace the object’s state if successfully accomplished.– Write recovery code in the catch clause.
• All these solutions work in a singly-threaded method. In a multi-threaded application all bets are off, and need to recourse to other ways to handle object’s consistency.
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
19
Beware
• Do not ignore exception handling!• Exception handling with blank braces
should raise flags.• An ignore exception can later cause another
exception in an unrelated piece of code!• There are cases where you may ignore an
exception, write a comment for the reason why is safe to ignore it!
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
20
Java support for encapsulation
• Field modifiers:– public – private– protected– none
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
21
Static uses in Java1. To define constants.
2. To define methods
1. These methods are called class methods, because they are independent of any of the instances of a class.
2. Instance methods rely on the state of the object, while class methods must be independent of them.
3. Using inheritance, static methods cannot be overwritten, they can only be overloaded. A typical programmer’s error is to overwrite a static method in a subclass, but in reality is only being overloaded.
4. Thus, polymorphism does not work with static methods.
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
22
Static uses in Java
1. Static method invocation is qualified not with an object reference, but with the actual class name.
2. The variables manipulated in a static method must be local variables or static variables.
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
23
Best programming practices
• USE DESIGN BY CONTRACT.– Identify class invariants and make sure all methods
maintain them.– Method specification includes require and ensure clauses as doc comments.
• Develop a test plan as part of analysis/design phase.
• Test each class independently from the system you are developing.
• Even better, use JUnit to make testing automated while supporting iterative design.
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
24
Best programming practices
• When writing code, get used to re-read your code carefully to uncover commonly made design flaws:– Repetitive code– Large methods– Lack of use of polymorphism– Large objects– …. Etc
• This activity goes by the name of refactoring• Successful refactoring needs to be supported by
automated testing. Changing code without testing it is asking for big trouble down the line.
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
25
Fundamental System Decomposition: MVC
• Any system written using object must exhibit the following decomposition:– Model: the set of classes which solve problem.
These component is independent of the interface being uses by the system.
– UI: the set of classes to provide an interface to the model.
– Data: the set of classes that provide data to the UI or the Model.
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
26
Static diagram for fundamental decomposition
Data Model UI
presentsconsumes
consumes
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
27
Fundamental Software Development Principles
• Cohesion: A module should model one well defined concept; its functionality must only deal with supporting the concept being modeled.
• Coupling : a module’s collaborators should be small in number and it should interact through a well defined interface.
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
28
Tools for Design: Inheritance and Composition
• Inheritance– strong coupling between components
– allows modification of components being reused
– Making a new class involves programming
– static relationship
• Composition – powerful reuse technique, difficult to understand by examining
static program text.
– Composition’s core class can be changed at run-time
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
29
Delegation
• Composed object uses its components to implement its interface. Usually a composed object receives a messages which it forwards to one of its components for execution. This is called delegation.
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
30
Uses of inheritance
• Identifying common functionality among a collection of classes
• providing an implementation of a method in an abstract class
• providing an alternative implementation
• refining the implementation of a method
• extending functionality of an existing class
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
31
Concrete classes, abstract classes, interfaces
• When should we subclass, when should we compose?
• When to use an abstract class, when to use an interface?
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
32
Abstract classes
• To model a generalized object
• Specification of an abstract class ought to be stable
• Should factor out common implementation details of its subclasses
• Mechanism used to exploit polymorphism
• Abstract classes can be extended without breaking running code.
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
33
Interfaces
• Model to generalize functionality• they are by definition abstract, no aspects of
its implementation is fixed.• A way to multiple inheritance: A class can
implement one or more interfaces• Allows for a more generalized used of
polymorphism• Interfaces cannot be modified• They are the key to pluggability
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
34
Interfaces and the software life-cycle
• Design: serve as a stabilizing element in the specification and implementation of classes
• Implementation: compiler checks that class implementing interface fullfills contract
• Integration: well-established interfaces are glue for composed classes and subsystems
• Testing: logical errors are limited to a subset of methods
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
35
Inheritance and composition
• Advantages of inheritance:– code reuse– polymorphism– extension of an existing class
• dis-advantages of inheritance– superclass and subclass are strongly coupled;
changes to superclass affect suclass, and subclass cannot change specification of superclass methods
– It’s a static feature
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
36
• Advantages of composition– code reuse as black box reuse– can change composed object’s core class at run-
time; ie, it’s a dynamic property of object– Supports stronger encapsulation than
inheritance. Changes to core class does not affect specification of composed class. And vice-versa, changes to composed class do not affect core class.
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
37
• Dis-advantages of composition– lose polymorphism.!!!– Can gain it back: compose with interfaces and
have core classes implement those interfaces
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
38
Mis-uses of inheritance
• To model roles
• To provide implementation alternatives to a given abstraction
• To model option features of an object
• Consequences:– class explosion
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
39
• Favor composition over inheritance• Inheritance should not be used just for code
reuse or to take advantage of polymorphism• It is harder to maintain inheritance based
code than composition based code. • Use inheritance
– when the complete interface of the superclass applies to the subclass candidate
– there is a permanent is-a relationship– superclass is stable.– For specialization
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
40
• Composition can be used– some features of core class are irrelevant, ie,
new class is not a true functional subtype – to provide implementation to some specific
functionality. – high proportion of code of base class need to be
rewritten– Use composition to extend functionality by
delegating to more appropriate objects. • Interfaces can be used
– to maintain separation of between specification and implementation
– to provide reuse and polymorphism across hierarquies
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
41
Accommodating update of object’s class
• Example: modeling with inheritance
• “transmute” problem: via copying & delete• With composition: use “simple”
assignment to component being updated.
Worker
SalesW HourlyW FixedW
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
42
Example
• Need to model student• Later on need to model PT, FT student
(beware not to model attributes with classes)
Student
FTPT
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
43
• Later own, need to consider graduate studentStudent
FTPT Grad
FTGradPTGrad
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
44
Later on ...Add student worker
Student
FTPT Grad
FTGradPTGrad
AGGGGHHHHHHHHHHHHHHHHH!!
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
45
Alternative
• Define : Student with subclasses undergrad, GradStudent
• Define: Status with subclasses PT, FT
• Define: Worker with subclasses FTW, PTW
• Now based on student we compose to get– a student who is part-time and ft worker– a grad student full time and part time worker
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
46
Example: Account class
• Designed to include– customer information:
• name
• address
• account identification number
• Design not cohesive: two abstractions– customer information– account
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
47
Cohesion
• Limitations introduced due to the one-to-one correspondence of the two abstractions– one customer with several accounts– join accounts
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
48
Class specialization
Composing on the two dimensions: class explosion.
One possible solution: multiple inheritance. More trouble that what solves. Problem: inheritance diamond.
Account
Individual InstitutionCash Acc Porfolio Ac
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
49
Cash Acc Porfolio Ac Individual Institutional
Account Customer* 1..*
owner
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
50
Inheritance vs composition
• Examples: – Sensor, remote Sensor– Subclasses of Thread, not a good choice– Subclasses of Observable
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
51
Rules to achieve cohesion
• An attribute should have a single value and not have structure (repeating groups)– Account with many different currencies– balance has as value list of <currency,balance>
• An attribute should describe an instance of its containing class– customer name, address, etc do not describe an
Account instance
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
52
An example
• Design a Button class to control a lightbulb
• software to reside on table lamp
• Somehow fact that user has pressed button is communicated to software
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
53
First solution
LightBulbcontains
Button
Not reusable Reusable
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
54
Second solution
Button
PumpButton LightBulbButton
LightBulb
contains
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
55
Third solution
Button ButtonServer
contains
LightBulb
Reusable Not so Reusable
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
56
Forth solution
LightServer LightBulbcontains
Button ButtonServer
contains
Reusable Reusable
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
57
Trade-off Evaluation
• Second Solution : less code but – locks the relationship between a
Button object and object it controls
• Fourth solution : more flexible.– Any Button object can be used to
control any derivative of ButtonServer.
– allows many different objects to be controlled by the same Button at different times.
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
58
Engineering Tradeoff
• Choice of solution to use involves an engineering tradeoff.
• Fourth solution: – flexibility V.S.– speed and complexity overhead
• Second solution– resource frugal V.S.– much less flexibility
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
59
• Design 1 is the simplest; • simplicity of design does not
necessarily relate– simplicity of maintenance, – possibility or simplicity of reuse.
• in order to create a design that is maintainable and reusable, some conceptual effort must be applied.
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
60
• There is a cost to applying object-oriented design.
• Good object-oriented design will generally be more complex than procedural design
• Extra complexity: – infrastructure to manage dependencies
• Don’t begrudge extra complexity. Payoff– maintainance– reuse
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
61
Cohesion
• Abstraction unit model one concept• functionality to support concept only
– Design goal: minimize features• A class with high cohesion :
– maintains– localizes– protects
features necessary to perform primary role
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
62
Cohesion
• Provide “enough” features to support role• This implies:
– not adding derived functionality that can be perform with them
• This enables– superimposed layers to control components in
different ways
• Goal: high cohesion of components
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
63
Coupling
• module’s collaborators – should be small in number – should interact through well defined interface
• Unit minimizes demands on environment
• Goal: low coupling and type of coupling
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
64
Representational coupling
• Should not depend on representation or computational detail of another one
• Addresses:– interchangeable parts– multiple representations– prototype evolution– system evolution– performance tuning– Extensibility– External components– Standarization– Testability– Frameworks
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
65
Value coupling
• classes should be written so that operations are independent of particular values– when special values occur, use classes to
classify and manipulate them(State pattern)
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
66
Subclass coupling
• a client refers to a subclass object through subclass reference rather than superclass reference.
• In Java use of abstract classes and interfaces to raise reuse opportunity
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
67
Code coupling (Control?)
• The definition of concrete operations should be decoupled from the context in which they are employed
• Sequential vs. concurrent execution– Example: how to get an item to a list vs when
to get it.– Should be possible to define how to get it for
either situation
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
68
Inheritance Coupling
• this is a compile-time binding
• cannot be discarted at execution time
• This is the old problem: • inheritance vs. composition
– if you compose: • may design zero or more instances of the object
• can set/change its value at run-time.
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
69
Rise of Coupling in OO
• An OO system is a network of interactive objects
– interaction between objects creates the coupling (dependence)
– the interaction results due to implementation of relations among the objects
– Thus coupling in OO system is necessary, but
– it creates dependencies among classes, components, subsystems
• activity of good analysis and design: management of dependencies
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
70
What’s wrong with dependencies?
• End result due to lack of management of these dependencies:– Brittle software: changes propagate beyond expected
boundaries
– OR
– Hard software: it does not respond to changes
• Opposite this state of affairs:– units of abstraction localize possible changes
– and
– abstraction units are change-responsive: flexible
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
71
How to get flexible abstractions?
• Actively design for that characteristic– Start with cohesion & coupling of abstractions
• look for : high cohesion, low / kind of coupling
– identify and abstract/encapsulate what varies– Test flexibility of your abstractions
• produce an active list of possible changes to measure flexibility against. NNB
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
72
Binding of Coupling
• Static coupling– established at compilation time– need definitions of dependents for compilation
• Dynamic coupling– two classes are dynamically coupled if their
instances call methods of one or the other at run-time
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
73
Transitivity in Dependencies
• If A depends on B, B depends on C, hence A depends on C
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
74
Coupling Best practices
• Identify subsystems– closed for changes– reused as a whole– well-defined purpose
• Reduce static coupling between different subsystems’ classes. Pay special attention to transitive coupling
• Reduce dynamic coupling
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
75
Software Principles
• Information Hiding principle:• .A client does not need to know how a module
(system) work to use it.• .A client should not be allowed to extend the
system knowing how the system works.
• Software Continuity principle: small changes in the specification should produce small changes in the implementation of the module (system)
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
76
Software Principles. Cont....
• The OCP (Open-Closed Principle),
• The LSP (Liskov substitution Principle),
• The DIP (Dependency Inversion Princ),
• The ISP (Interface Segregation Principle),
• The RREP (Reuse/Release Equivalency principle),
• The CCP (Common Closure Principle),
Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads
77
Software Principles. Cont....
• The CRP (Common Reuse Principle)
• The ADP (Acyclic Dependencies Principle),
• The SDP (Stable Dependencies Principle)
• The SAP (Stable Abstractions Principle)
• The LoD (Law of Demeter)