Class Design - Part 1 35 1

advertisement
Class Design - Part 1
35
1
Note: there is so much more than below…
 More facts regarding Class Design
Re-look at Persistent Classes
Re-look at Class Operations
 Scope of Operations
Methods
States – State Charts
Attributes
 Defining Dependencies
and Associations
 Generalizations
Multiple Inheritance
Polymorphism
35
2
We want to:
 Refine relationships, operations, and attributes
 Focus on fleshing out the details of a particular class
 operations needed and allocated to classes;
 how operations / methods collaborate to support the
responsibilities allocated to the class.
 Later:
 Address non- functional requirements
 We will look at Design Patterns in the future.
35
3
Class Design in Context
Architectural
Analysis
Describe
Architectural
Concurrency
Design
Architect
Review the Architecture
Architecture Reviewer
Subsystem Design
Use-Case
Analysis
Designer
Describe
Distribution
Review the
Design
Use-Case
Design
Design
Reviewer
Class
Design
This is where we stand. Recall:
Architectural Design: decide on the infrastructure;
pieces and parts of the architecture and how they interact).
Use Case Design is where the responsibilities of the system are allocated to the pieces/parts;
Subsystem and Class design are where we detail the specifics of the pieces/parts.
35
4
How Many Classes Are Needed?
Many, simple classes means that each class
 Encapsulates less of the overall system intelligence
 Is more reusable
 Is easier to implement (more cohesive…)
 Few, complex classes means that each class
 Encapsulates a large portion of the overall system
intelligence
 Is less likely to be reusable
 Is more difficult to implement
 Proper size may depend heavily on implementation
environment – classes should map directly to some
phenomenon in the implementation language in such a
way that the mapping results in good code.
 A class should have a single well focused purpose.
A class should do one35thing and do it well!
5
Recall: Boundary Classes – from Analysis
External System Interface:
 Note:
 Usually model as subsystem
 Oftentimes these interfaces have complex
internal behavior (hence the design modeling
as a subsystem)
Design (within Subsystem)
Analysis
MainWindow
SubWindow
MainForm
Button
35
DropDownList
6
Recall:
Entity Classes
(1 of 3)
 Entity objects are often passive and persistent
 In Analysis, we identified entity classes.
 These were ‘conceptual’ classes. Often taken from
domain model and expanded a bit. But these were not
software classes.
 These classes may have been associated with analysis
mechanisms for persistence, security, etc. representing
manipulated units of information.
 May be associated with legacy systems too.
 May be distributed…
 Performance concerns may suggest re-factoring of
persistent classes, causing changes to the Design
Model.
35
7
Entity Classes - Sample Re-factoring
 Have persistent class with five attributes.
 One attribute is not really persistent – used during runtime
but Use Cases tell us two attributes used a lot; two others less.
 In design, we would like to retrieve commonly used attributes
right away but defer others until asked for.
 But we don’t want a complex design for the client. So:
FatClass
- transientBookeeping
Analysis
<< entity >>
FatClass
- transientBookeeping
+ commonlyUsedAtt1
+ commonlyUsedAtt2
+ rarelyUsedAtt3
+ rarelyUsedAtt4
+ getCommonlyUsedAtt1()
+ getCommonlyUsedAtt2()
+ getRarelyUsedAtt3()
+ getRarelyUsedAtt4()
1
FatClassDataHelper
+ commonlyUsedAtt1
+ commonlyUsedAtt2
35
Design
1
FatClassLazyDataHelper
+ rarelyUsedAtt3
+ rarelyUsedAtt4
8
Entity Classes

From a data standpoint, will consider the FatClass to be a proxy in front
of the two real persistent data classes.

It will retrieve FatClassDataHelper from database when it is first
retrieved. Will retrieve FatClassLazyDataHelper in rare occasion when a
client asks for one of these attributes.

This is a view from a data-oriented perspective while retaining a
logical object-oriented view for clients to use.
FatClass
Analysis
<< entity >>
FatClass
- transientBookeeping
+ commonlyUsedAtt1
+ commonlyUsedAtt2
+ rarelyUsedAtt3
+ rarelyUsedAtt4
- transientBookeeping
+ getCommonlyUsedAtt1()
+ getCommonlyUsedAtt2()
+ getRarelyUsedAtt3()
+ getRarelyUsedAtt4()
1
FatClassDataHelper
+ commonlyUsedAtt1
35
+ commonlyUsedAtt2
Design
So, which would you rather
retrieve?? FatClass or
FatClassDataHelper?
1
FatClassLazyDataHelper
+ rarelyUsedAtt3
+ rarelyUsedAtt4
9
Recall: Control Classes
 What Happens to Control Classes?
 Are they really needed? Split them?
 If they seem like just ‘pass throughs’ from the boundary
to the entity classes, eliminate them.
 Recall the purpose of Control Classes….
 Control Classes may become true design classes
for any of following reasons:
 Encapsulate significant control flow behavior
 Behaviors are to be distributed across multiple
processes and/or processors (often JSP, servlets…)
 The behavior they encapsulate requires some
transaction management
 A single analysis control class can easily become
two or more design classes.
35
10
Class Design Steps:
Identify Persistent Classes
 In Use-Case Analysis, (that is, going through use cases…)
 a vague notion that certain classes need to be persistent
 But this is just the 'tip of the iceberg' of system design.
 Now, in Class Design, get really specific about
 what the classes are, (are there more?)
 what their behaviors are (parameters, services, …et al), and
 what attributes these classes really have.
 Now, we must be certain
 which classes will have persistent instances, and that
 all persistent classes are mapped
to a storage mechanism.
35
11
 Persistent class: Any instance of the class that
requires its state to be preserved.
 A persistent class may have both persistent and transient
instances
 Labeling a class 'persistent' means merely that some instances of
the class may need to be persistent.
Client
Analysis
Design
Implementation
Class
Mechanism
Mechanism
Mechanism
(Conceptual)
(Concrete)
(Actual)
Legacy Data
Course
Student
Persistency
Persistency
RDBMS
SQL Server
New Data
Sybase;
Oracle…
OODBMS
35
ObjectStore
12
Important Note.
 Persistent classes may come from entity classes.
 May also be needed to handle some non-functional
requirements…
 Examples:
 Persistent objects needed to maintain information relevant to
process control, or
 Persistent objects needed to maintain state information
between transactions.
35
13
A Closer look at Classes
35
14
Class Operations
 Purpose
 Map responsibilities (analysis) (from use cases or
user stories) to operations (design) that
implement them
 Things to consider regarding class operations:
 Operation name, signature, and description
 Operation visibility
 Operation scope
 Class operation vs. instance operation
 Operations: define at most primitive level to
promote reusability and maintainability.
35
15
Class Operations: Name and Describe
 Provide appropriate operation names.
Indicate the outcome – e.g. getBalance().
Consistent across classes
 Define operation signatures
 operationName(parameter : class,..) : returnType
 Best to specify operations and their parameters using
implementation language syntax and semantics – if
you know it.
 Thus the interfaces will already be specified in terms
of the implementation language when coding starts.
  Helpful to provide short textual description,
including meaning of all parameters for an operation.
 (still not doing real detailed design; that is, the algorithm.
This is done during programming.)
35
16
Class Operation Signatures: Guidelines
 In addition to a short description of the
parameter, be sure to include:
 Parameters passed by-value or by-reference?
 If Call by Value, parameter cannot be changed in call.
 If Call by Reference, parameter may be changed in
call.
 Parameters optional?
 Default parameter values?
 Valid parameter ranges?
 (different implementations offer different options…
 The fewer the parameters, the better.
  less coupling; more understandable and
maintainable.
  Pass objects instead of “data bits” –
35
a rich strength of OO.
17
Discovering Additional Classes and Relationships
ClassA
Class2
op1(var1:Class2): Class3
• Parameters and return types may lead to discovery
of other classes.
• Operation parameters and return classes denote
a relationship between these classes and the
parameter class and/or the return class.
Class3
• In many cases, the relationships added to
support operation signatures are dependency
relationships. (This is a strong dependency!!)
What does the class
diagram above tell
you???
• Dependency relationships are discussed ahead.
• Dependency also applies to attributes as well as
operations..
35
Additional classes and relationships
may be added to
support signature
18
Class Visibility – How Noted?
 The following symbols are used to specify export control for
attributes and operations:

+ Public access

# Protected access

- Private access
 In Java we also have package visibility.
Class
- privateAttribute
# protectedAttribute
+publicOp()
# protectedOp()
- privateOp()
35
19
Class Operation and Attribute Scope.
 Determines number of instances of attribute or
operation
 Instance scope: one instance for each class instance (object)
(instance variables…)
 Class scope: one instance for all class instances (objects)
 Static variables in Java. Don’t need instantiations…
 Class scope: underline attribute/operation name
 Generally, we have instance scope; but can have class scope
for may other practical reasons: counters, global data
(cough) etc.
 Class scoped operations can only access class-scoped
attributes. (in Java, class scope  static)
Class
- classifierScopeAttribute
- instanceScopeAttribute
classifierScopeOperation()
35
instanceScopeOperation()
20
Example: Scope
<<entity>>
Student
- name
- address
- studentID
- nextAvailID : int
+ addSchedule(theSchedule : Schedule, forSemester : Semester)
+ getSchedule(forSemester : Semester) : Schedule
+ hasPrerequisites(forCourseOffering : CourseOffering) : boolean
# passed(theCourseOffering : CourseOffering) : boolean
+ getNextAvailID() : int
• Here, have a single class scoped attribute, nextAvailID; single classifier
scoped operation, getNextAvailID().
• Each Student instance has it’s own unique student-ID, name, address,
whereas, there is only one nextAvailID for all Student instances.
• The getNextAvailID() classifier scoped operation can only access nextAvailID.
• Why??
35
21
Example: See Visibility indicators…
<<Interface>>
ICourseCatalogSystem
<<control>>
RegistrationController
1
(from External System Interfaces)
0..*
(from Registration)
+ getCourseOfferings()
+ submitSchedule()
+ initialize()
+ saveSchedule()
+ getCourseOfferings() : CourseOfferingList
+ getCurrentSchedule(forStudent : Student, forSemester : Semester) : Schedule
+ deleteCurrentSchedule()
+currentSchedule
<<class>> + new(forStudent : string)
0..1
<<entity>>
+ getStudent(withID : string) : Student
Schedule
0..1
(from University Artifacts)
0..1
0..*
0..*
0..*
+registrant
0..1
<<entity>>
Student.
1
+alternateCourses
+primaryCourses
(from University Artifacts)
+ getTuition() : double
+ addSchedule(theSchedule : Schedule)
+ getSchedule(forSemester : Semester) : Schedule
+ deleteSchedule(forSemester : Semester)
+ hasPrerequisites(forCourseOffering : CourseOffering) : boolean
# passed(theCourseOffering : CourseOffering) : boolean
<<class>> + getNextAvailID() : int
+ getStudentID() : int
+ getName() : string
+ getAddress() : string
0..2
0..4
<<entity>>
CourseOffering
(from University Artifacts)
Note: the <<class>> operations.
Note: + classes (invoked by clients);
# only invoked by defining class/subclasses,
35
22
(usually correspond to reflexive operations
on interaction diagrams; (more )
Review: Package Element Visibility
Only public classes
can be referenced
outside of the owning
package
PackageA
Class A1
Class A2
A
Class A3
PackageB
B
+Class B1
-Class B2
Class has Public visibility
Class has Private visibility
Can specify visibility for
package elements
(i.e., classes….) in
same way as class
attributes / operations
(can protect classes)
Shows how other
packages can access
the elements owned by
the package.
(Have visibility symbols
for packages)
OO Principle: Encapsulation
35
23
Defining Dependencies
and Associations
35
25
Define Dependency
 What Is a Dependency?
 A relationship between two objects
 In Analysis, we assumed relationships were ‘structural’
that is,
associations,
aggregations,
composition.
These refer to parts, numbers, coincident lifetimes, one–to–
many, etc.
 In Design, we must decide what type of communication
pathway is required.
26
Dependency - more
 A dependency relationship denotes a semantic
relationship between model elements, where a change in
the supplier may cause a change in the client.
 Semantics focuses on the relation between signifiers,
such as words, phrases, signs, symbols, ….
 What would happen if java.sql changed, where all of our,
say, persistency mechanisms use (depend on) the objects in
this package?
 Need to

Determine what causes the supplier to be visible to the client
35
Client
Supplier
35
27
Dependencies vs. Associations*
 Associations are structural relationships


i.e., numbers of one type related to another; parts, lifetimes, ….
Aggregates (has_a) generalization (is_a), …
 Dependencies are non-structural (semantic) relationships.
Dependencies are strong relationships!
Supplier2
Dependency
Association
1
Supplier1
0..1
Client
buyer
broker
Usually the association will have
numbers relating objects of one
type to the other; roles too…
28
Communication pathways to Suppliers
a.k.a. how are suppliers made visible to clients
 Four “communications pathways” to supplier;
that is,
how are suppliers made ‘visible’ to clients.
 Local variable reference –
 Supplier object is declared locally (created temporarily
during execution of an operation / method)
 Client object declares a local variable within a specific
method within client.
 Parameter reference –
 supplier object is a parameter to, or the return class of an
operation in the client object.
 A method in client has a formal parameter of type supplier
or the method returns an object of type supplier…

(think: File Reader…. These return other objects dealing with I/O…
 Global reference – supplier object is global.
 Self-explanatory
 Field reference – The supplier object is a data member in
35
29
the client object.
 There is an instance variable within object of type supplier.
Dependencies vs. Associations: Look at Relationships:
What are they going to be/become?
 Associations and aggregations is a type of
communication pathway that are structural relationships
(Visibility = Field Visibility; four slides up).

We’re talking about ‘Association relationships’ realized by variables
that exist in the data member section of the class definition.

Field: ALL objects have own copy of instance variables!

Each class stands on it's own.
 Dependency is a type of communication pathway that is a
more temporary type of relationship –
(Visibility = Global, Parameter, & Local; next three slides)
 (Parameter – method may/may not be invoked; Local? Temporary

life for execution of method; Global– life apart from object…)
 Any relationships not associations are dependency
35
30
Local Variable Visibility  Dependency
 The op1() operation contains a local
variable (an object) of type ClassB
(local variable is not a parameter)
 Hence there is a dependency between
these two classes.
boolean op1(….) // method in ClassA
{
ClassB myClassB = new ClassB (…)
ClassA
op1 ()
// note that this is indeed local!
…
ClassB
35
31
Parameter Visibility  Dependency
 The ClassB instance is passed to the
ClassA instance – hence a dependency.
ClassA
op1 (param1: ClassB)
ClassB
Format: object name; Class
e.g. op1(myClassB: ClassB)
If op1 is invoked, it is passed an
object of type ClassB
35
32
Global Visibility  Dependency
 The ClassUtility instance is visible
because it is global. Clear dependency.
 op1() uses something in a ClassUtility
object.
ClassA
op1 ()
ClassUtility
utilityOp ()
35
33
Field Visibility  Association
 The ClassB instance is visible. There is an
‘association.’
 Not temporary; Every instance of ClassA has an
object of ClassB
ClassA
ClassB myClassB;
op1 ()
instance variable
ClassB
utilityOp ()
35
34
Example:Define Dependencies (before looking for dependecies)
(VOPC Register for Courses Use Case)
Up to here, most relationships have been
associations and aggregations. (Analysis)(
Now, will see how some of these are refined
into dependencies. (design)
Much was done during analysis!
<<Interface>>
ICourseCatalogSystem
(from External System Interfaces)
+ getCourseOfferings(forSemester : Semester) : CourseOfferingList
1
0..*
<<control>>
RegistrationController
(from Registration)
courseCatalog
currentSchedule
The dependency
+ // submit schedule()
0..1
shown (next slide) + // save schedule()
+ // create schedule with offerings()
was previously
+ // getCourseOfferings(forSemester) : CourseOfferingList
defined in the Define
0..1
Ops section to support
1
the Schedule operation
registrant
0..1
signatures.
0..1+ submit()
+ // save()
# any conflicts?()
+ // create with offerings()
0..*
0..*
0..*
alternateCourses
primaryCourses
0..2
0..4
- name
- address
- StudentID : int
<<entity>>
CourseOffering
(from University Artifacts)
- number : String = "100"
- startTime : Time
- endTime : Time
- days : Enum
+ addSchedule(theSchedule : Schedule, forSemester : Semester)
+ getSchedule(forSemester : Semester) : Schedule
+ hasPrerequisites(forCourseOffering : CourseOffering) : boolean
# passed(theCourseOffering : CourseOffering) : boolean
+ addStudent(studentSchedule : Schedule)
+ removeStudent(studentSchedule : Schedule)
+ new()
+ setData()
<<entity>>
Student
(from University Artifacts)
All associations
/aggregations
should be
examined to
see if they are
dependencies.
<<entity>>
Schedule
(from University Artifacts)
- semester
35
35
Example: Define Dependencies (after 1 of 2)
Changed one association to a dependency relationship. (This change discussed on ‘next’ slide)
Here, during a registration session, the Registration Controller works with a single Student, the registrant,
and one Schedule, the current Schedule for the Student.
<<Interface>>
These instances need to be accessed by
ICourseCatalogSystem
more than one of the Registration Controller’s,
(from External System Interfaces)
operations so Field Visibility is chosen
+ getCourseOfferings(forSemester : Semester) : CourseOfferingList
from Registration Controller
Global visibility
to Student and from
Registration Controller
<<entity>>
<<control>>
Schedule
to Schedule.
RegistrationController
(from
University Artifacts)
(from Registration)
Thus relationships
currentSchedule - semester
remain
+ // submit schedule()
0..1+ submit()
0..1
+ // save schedule()
associations.
+ // save()
+ // create schedule with offerings()
# any conflicts?()
(more ‘permanent’)
+ // getCourseOfferings(forSemester) : CourseOfferingList
Field
+ // create with offerings()
0..*
0..1
A Student
manages his/her
own Schedules,
so Field visibility
is chosen from
Student to
Schedule –
and relation
remains
aggregation.
Again, more
‘permanent.’
Field visibility
1
registrant
0..1
<<entity>>
Student
(from University Artifacts)
- name
- address
- StudentID : int
see Schedule as
parameter below
+ addSchedule(theSchedule : Schedule, forSemester : Semester)
+ getSchedule(forSemester : Semester) : Schedule
+ hasPrerequisites(forCourseOffering : CourseOffering) : boolean
# passed(theCourseOffering : CourseOffering) : boolean
35
More 
0..*
alternateCourses
0..2
0..*
primaryCourses
0..4
<<entity>>
CourseOffering
(from University Artifacts)
- number : String = "100"
- startTime : Time
- endTime : Time
- days : Enum
+ addStudent(studentSchedule : Schedule)
+ removeStudent(studentSchedule : Schedule)
+ new()
+ setData()
36
Parameter visibility
see Course Offering in
Student as parameter
Example: Define Dependencies (after; more explanation)
Course Offerings are part of semantics of what defines a Schedule (courses Student has
selected). Thus Field visibility is chosen from Schedule to CourseOffering; relationships
remain associations.
The Student class has several operations
where CourseOffering appears in the
parameter list. Thus, Parameter visibility
is chosen from Student to
Global visibility
CourseOffering.
<<Interface>>
ICourseCatalogSystem
(from External System Interfaces)
+ getCourseOfferings(forSemester : Semester) : CourseOfferingList
<<entity>>
Schedule
(from University Artifacts)
- semester
<<control>>
RegistrationController
(from Registration)
It is envisioned
currentSchedule
the course Catalog+ // submit schedule()
0..1+ submit()
0..1
schedule()
System may need ++ //// save
+ // save()
create schedule with offerings()
# any conflicts?()
to be accessed by + // getCourseOfferings(forSemester) : CourseOfferingList
Field vis
+ // create with offerings()
0..*
multiple clients
0..1
0..*
0..*
in the system, so
alternateCourses
Field visibility
primaryCourses
1
registrant
Global visibility
0..2
0..4
0..1
was chosen –
<<entity>>
<<entity>>
CourseOffering
and relationship
Student
(from University Artifacts)
becomes a
(from University Artifacts)
- number : String = "100"
- name
- startTime : Time
dependency. - address
- endTime : Time
- StudentID : int
- days : Enum
+ addSchedule(theSchedule : Schedule, forSemester : Semester)
+ getSchedule(forSemester : Semester) : Schedule
+ hasPrerequisites(forCourseOffering : CourseOffering) : boolean
# passed(theCourseOffering : CourseOffering) : boolean
+ addStudent(studentSchedule : Schedule)
+ removeStudent(studentSchedule : Schedule)
+ new()
+ setData()
35
37
Parameter visibility
Download