The Author Online Book Forums are Moving

The Author Online Book Forums will soon redirect to Manning's liveBook and liveVideo. All book forum content will migrate to liveBook's discussion forum and all video forum content will migrate to liveVideo. Log in to liveBook or liveVideo with your Manning credentials to join the discussion!

Thank you for your engagement in the AoF over the years! We look forward to offering you a more enhanced forum experience.

khalopti (1) [Avatar] Offline

In Section 3.1.2 An example domain model, you introduce the PendingOrder and Order classes. You state that "In theory we could have used the Order class to represent both the order being entered and the placed order, but this would have made the application more complex. Using two separate classes simplifies the design."

Please can you elaborate on how the application becomes more complex if e.g. PendingOrder is replaced by Order, with an extra state value "PENDING" used to distinguish the two? I'm a fan of the DRY (Don't-Repeat-Yourself) principle, and the PendingOrder/Order approach seems to violate this.

Thanks in advance, and thanks for the book!
simbo1905 (30) [Avatar] Offline
Re: PendingOrder and Order - a violation of DRY?
If you want to add different fields both pre- and post- the business lifecycle event of "Customer Places Order" then you may well end up adding fields and going with a class hierarchy. To do that hibernate adds a discriminator column to the table which says which class to use for each row and store the "before" and "after" entity in two different rows which helps with auditing what happened in the app.

If you take a step back and look at the idea of adding a "workflow" status flag to a single entity type only it looks a lot like a hibernate class discriminator. So why not use different types so that your compiler can prevent you from mixing up objects in the "before" and "after" states? That might be valuable even if they don't have different fields but an abstract ancestor to hold all the shared fields to avoid any duplication. The concrete subclasses can have their own behaviours and you get all the wholesome goodness of polymorphism and generics.

Note that you can add a copy constructor for the "after" object to copy itself from the before object using protected members. Then will end up with two rows one for each entity so that you can see things like "creation time", "last update time", "last use to modify", "use who created" of both the the before and after entities which is useful for auditing what happened in the system.

Another point to consider is that as well as DRY you should aim to have each class do one thing and one thing well at a single level of abstraction. Having an entity model both the record in the DB and the workflow status of the system is clearly having it do more than one thing at two different levels of abstraction. Consider having explicit domain model to model the state of the system: jBoss jPDL library has great capability to embed as a set of out-of-the-box services and entities that model system workflow.