The post-condition defines what the state of your application (or object, depending on the level of abstraction) should be after the operation for it to be considered as successful. For the readEmployee
operation, for example, the post-condition would be that:
- a new
Employee
instance is created.
- the
Employee
instance contains attributes matching the database values.
- the database connection is closed.
I like to think of "pre-condition" and "post-condition" as the "state of mind" of your application before and after an operation has executed, respectively. As you can imagine, it's more a thought process than a coding exercise when you do DbC.
(If you do unit-testing, states make it clear what needs to be covered by your tests. Basically, you end up testing the "state of mind" of your application.)
Interestingly, if you consider the reverse of DbC, you realise that to identify what operations your application (or object) should expose, it is simply a matter of listing what states it can have and how it transitions between these states. The actions that you need to take to make these transitions then become your operations, and you do not have to bother with implementing operations that do not lead to any desired states. So, for example, you probably want the following states for your application.
- Employee details added (S1)
- Employee details loaded (S2)
- Employee details updated (S3)
- Employee details deleted (S4)
The following state transitions are possible.
- S1 -> S3 (add new employee, update the details)
- S1 -> S4 (add new employee, delete the employee)
- S2 -> S3 (load employee details, update employee details)
- S2 -> S4 (load employee details, delete employee)
- S4 -> S1 (delete employee, add new employee)
- S2 -> S1 (load employee details, add new employee)
- S3 -> S1 (update employee details, add new employee)
- S3 -> S2 (update employee details, load employee details)
Based on the above, you can write your operations in such a way that only valid transitions are allowed, with anything else giving rise to errors.
Impossible state transitions:
- S4 -> S2 (cannot delete an employee, then load their details)
- S4 -> S3 (cannot delete an employee, then update their details)
State modeling is probably the most important part of designing objects, so you're asking the right questions. If you want a good resource on state modeling, get Object Lifecycles Modeling the World in States from Sally Shlaer / Stephen Mellor. It is quite an old book and costs almost nothing on Amazon, but the principles it introduces form the basis of modern UML -- incidentally, the notation used in the book looks nothing like UML.
I realise I did not touch on database state, but at the conceptual level, the database layer is just another system of states and the same principles apply.
I hope this was useful.