Title: Encapsulation and Data Abstraction
1Encapsulation and Data Abstraction
- Testing
- Applications in Smalltalk
2Encapsulation and Data Abstraction
- An object should hide design decisions from its
users - what is stored / what is computed
- classes used
- Cant hide everything
- Interface of object
- Interface of parameters of object
3Encapsulation
- Class contains variables and all the code that
accesses the variables. - Code should go with data.
- Over use of accessing methods is a sign of poor
encapsulation - Code that uses a lot of accessing methods of an
object should be moved to that object
4Encapsulation
- (aPoint x squared aPoint y squared) sqrt
- aPoint r
- Some patterns (State, Strategy) break
encapsulation. These are exceptions to the
general rule that code should go with data.
5Inside/outside
- Class describes the implementation of an object
- Users care about specifications of object
- Interface (Java, C)
- Pre and post-conditions (Eiffel)
- Tests, examples, English description (all
languages)
6Tests
- See if feature works
- Make sure changes dont break anything.
- Document features.
- Measure of completeness.
7Test-driven development
- Write test for new feature first, then implement
the feature. - Stop when tests work.
- Use the simplest design that makes all the tests
work - Refactor to eliminate duplication
8SUnit
- The testing framework.
- Each test is written in a subclass of TestCase.
- Test is a method of the form testXXX
- Each subclass is a group of related tests.
9TestRunner
XProgramming.SUnit.TestRunner open
10Important TestCase methods
- assert aBoolean
- deny aBoolean
- should aBlock
- should aBlock raise anException
- shouldnt aBlock
- shouldnt aBlock raise anException
11Test first design
- How should feature work?
- Give example
- Write test case
- Make test work
- Write another test case
- Make test work
- ...
12Problems with test first
- What about testing GUIs?
- What about testing real-time systems?
- Tests show the presence of flaws, not their
absence. - What about design?
13But you cant test everything!
- Testing increases your confidence.
- Testing involves tradeoffs - better testing is
more expensive. - Testing is never perfect you cant afford
perfection. - Zero testing is always wrong you must decide how
much is enough.
14You cant test everything
- You cant specify everything.
- Automated tests with Sunit are easy and cheap
most of the time. - Hard to test hardware.
- Hard to test concurrent systems.
- Most parts of a system are easy to test write
automated tests for them.
15Finding abstractions
- Do one thing
- Eliminate duplication
- Keep rate of change similar
- Decrease coupling, increase cohesion
- Minimize interfaces
- Minimize size of abstractions
- Minimize number of abstractions
16Do one thing
- Method should do what its name says
- Class should be what its name says
- Break complex classes/methods into simpler ones
17Eliminate duplication
- (Ranks indexOf rank) lt (Ranks indexOf argument
rank) - self rankIndex lt argument rankIndex
18Keep rate of change similar
- Separate initial conditions from an algorithms
temporary variables - Separate tax tables from employee data from time
cards - Use timer to separate quickly changing
information from slowly changing
19Decrease coupling, increase cohesion
- Coupling is dependencc between components
- Cohesion is dependence within a component
20Minimize interfaces
- Use the smallest interface you can
- Use Number instead of Float
- Avoid embedding classes in names
- add instead of addNumber
- Dont check the class of an object
21Mimize size of abstractions
- Methods should be small
- median size is 3 lines
- 10 lines is starting to smell
- Classes should be small
- 7 variables is starting to smell
- 40 methods is starting to smell
22Minimize number of abstractions
- Can only learn 4-5 new things at a time. 3 is
better - A class hierarchy 6-7 levels deep is hard to
learn - Break large system into subsystems, so people
only have to learn part of the system at a time
23A Payroll System
- PayrollSystem keeps track of employees.
- Employee knows salary, how much has been earned,
how much has been payed, how much taxes have been
withheld. Employee should be able to tell us
about past transactions, not just current
balances.
24Object Model for Payroll
A class with a method post
abstract class
EmployeeTransaction
PayrollSystem
Employee
date
postTo
abstract method
post
A payroll system has a set of employees.
Paycheck
SalaryChange
salary
pay, taxes
An employee has a set of transactions (and a
transaction is for an employee)
Timecard
Timecard, paycheck and salarychange are kinds of
employee transactions
hoursWorked vacation
25Employee
- Smalltalk.CS497rej defineClass Employee
- superclass Core.Object
- indexedType none
- private false
- instanceVariableNames 'name transactions salary
earned paid withholding accruedVacation taxRule ' - classInstanceVariableNames ''
- imports ''
- category 'Payroll'
26Employee Comment
- (View/Comment in RB)
- I represent an employee in a payroll system.
Thus, I keep track of the number of hours worked,
the wages paid, the vacation accrued, the taxes
withheld, and so on. My values change only when
transactions are posted to me. Transactions are
subclasses of EmployeeTransaction.
27(continued)
- Variables
- name ltStringgt
- transactions ltCollection of Transactions,
sorted by date postedgt - salary ltNumbergt
- ...
- taxRule ltTaxRulegt
28Hiding classes
- Employee knows class Timecard
- Users of Employee do not
- Employee creates Timecards for users
29Using Employee
- ralph
- ralph Employee new name 'Ralph Johnson'.
- ralph changeSalaryFor (Date newDay 5 year
1996) to 20. - ralph postTimeCardFor (Date newDay 10 year
1996) hoursWorked 40 - vacation 0.
30Testing Employee
- EmployeeTest is a subclass of TestCase
- testOvertime
- day1 ralph
- day1 Date newDay 5 year 1996.
- ralph Employee new named 'Ralph Johnson'.
- ralph changeSalaryFor day1 to 20.
- payroll addEmployee ralph.
- self employee ralph hours self aLittleOvertime
starting day1. - self assert ralph amountEarned 3500.0
31Initializing an Employee
- named aString
- name aString.
- transactions OrderedCollection new.
- salary 0.
- ...
- taxRule SingleTaxRate
32Complete Creation Method
- Employee has the class method
- named aString
- self new named aString
33Timecard
- Timecard is a subclass of EmployeeTransaction
- with instance variables 'hoursWorked' and
'hoursVacation '
34Initializing a Timecard
- date aDate employee anEmployee worked hoursW
vacation hoursV - date aDate.
- employee anEmployee.
- hoursWorked hoursW.
- hoursVacation hoursV
35Complete Creation Method
- Timecard has class method
- date aDate employee anEmployee worked hoursW
vacation hoursV - self new date aDate employee anEmployee
worked hoursW vacation hoursV
36Using a Timecard
- Employee has method
- postTimeCardFor aDate hoursWorked hoursW
vacation hoursV - self postTransaction (Timecard date aDate
employee self worked hoursW vacation hoursV)
37Initialization Patterns
- There should be one or more methods that
initialize object. They should be in protocol
"initialize-release". - There should be one or more class methods that
create initialized objects. They should be in
protocol "instance creation".
38Processing a Transaction
- In Employee
- postTransaction aTransaction
- aTransaction postTo self.
- transactions add aTransaction
39Processing a Timecard
- postTo anEmployee
- money overtime nonovertime
- overtime (hoursWorked - 40) max 0.
- nonovertime hoursWorked min 40.
- money (overtime 1.5 nonovertime)
anEmployee salary. - anEmployee incrementEarned money.
40Processing a Timecard
- salary
- salary
- incrementEarned anAmount
- earned earned anAmount
41Employee Action Protocol
- All changes to an Employee should be recorded as
transactions. - postTimeCardFor aDate hoursWorked hoursW
vacation hoursV - self postTransaction
- (Timecard date aDate employee self worked
hoursW vacation hoursV)