开发者

Larman's System Operation Contracts - CRUD example

I have some confusion with applying Larman's system operation contracts (OO Analysis from book Applying UML and Patterns) on CRUD-like operations. More precisely, I'm confused with postcondition part.

For example, if I have CRUD system operations looking as follows:

createEmployee(employee:Employee), 
readEmployee(employeeId:int), 
updateEmployee(employee:Employee), 
deleteEmployee(employeeId:int)

what would be postcondition on, for example, readEmployee system operation, or some other operation like searchEmployees etc?

For example: for read operation, system needs to read record from database, instantiate domain object, set attribute values on domain object (set relations also) and that's it. Does it means that postconditions are above mentioned - instance creation, changes on attributes, etc. Or, read operation does not have any postcondition. None of this does sound logical to me.

My confusion is about relation between domain model (state) and database (state). I just don't get implications which above operations will have on domain model. I always think in way that the database is a开发者_开发技巧 place that preserves the state of the system. After I create employee, its object's state will be persisted in database... But what happens with domain model state?


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.


My interpretation of Larman's contracts is always with respect to the domain model. Larman clearly states there are only 5 types of post conditions:

  1. Instance creation
  2. Instance deletion
  3. Attribute change of value.
  4. Associations formed.
  5. Associations broken.

Therefore, a Read (or search) operation would have no post conditions, at least not on the elements that are being read or searched. For example, if 10,000 users performed reads/searches in one day, but never did any of the other operations (C, U, D), there would be no change to the objects in the domain.

There is an exception to this, however, in domains where searches/reads are remembered. For example, Google surely keeps track of searches. In this case, doing a search has the postcondition of creating a new object in their domain model, e.g., A Search instance s was created (instance creation).


The confusing comes form mentioning data model relation within the contract template that Larman provided as in :

Contract CO2: enterItem
Operation: enterItem(itemID : ItemID, quantity : integer)
...
sli was associated with a ProductSpecification, based on itemID match (association formed).

The detail referential properties of the database should not be mentioned in the operation contract. It is better to leave it as: "sli was associated with a ProductSpecification".

In fact, it is one of the things that Larman's operation contracts does not talk about in much detail. Think about a contract for an operation that calculates a total number of items and return the total ! seems that it cannot be written as an operation contract.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜