views:

71

answers:

3

Ok, 'Fat' Model and Transaction Script both solve design problems associated with where to keep business logic. I've done some research and popular thought says having all business logic encapsulated within the model is the way to go (mainly since Transaction Script can become really complex and often results in code duplication). However, how does this work if I want to use the TDG of a second Model in my business logic? Surely Transaction Script presents a neater, less coupled solution than using one Model inside the business logic of another?

A practical example...

I have two classes: User & Alert. When pushing User instances to the database (eg, creating new user accounts), there is a business rule that requires inserting some default Alerts records too (eg, a default 'welcome to the system' message etc). I see two options here:

1) Add this rule as a User method, and in the process create a dependency between User and Alert (or, at least, Alert's Table Data Gateway).

2) Use a Transaction Script, which avoids the dependency between models. (Also, means the business logic is kept in a 'neutral' class & easily accessible by Alert. That probably isn't too important here, though).

User takes responsibility for it's own validation etc, however, but because we're talking about a business rule involving two Models, Transaction Script seems like a better choice to me. Anyone spot flaws with this approach?

+1  A: 

consider moving some of the business logic into the service layer

Ray Tayek
Thanks Ray, I'll investigate Service Layer as an option.
Benco
Benco
+1  A: 

For simple apps with little business logic, use Transaction Script. It's straight-forward (since each script typically maps with a software use case) and easy to implement (for example, you won't have to deal with complex OR mapping as in the case of rich domain model). In fact, spending much time on crafting a rich OO model for simple apps is, to me, an act of over-engineering.

For more complex apps (or when the previously simple apps become more complex), you'll almost certainly see the pitfalls of the Transcription Script pattern emerge, namely code duplication and rigidity in the transaction scripts (which by now might have become big balls of mud). In this case, a rich domain layer would make more sense.

Generally, I would start building apps using Transaction Script and slowly refactor it toward a richer domain model when the app grows.

Buu Nguyen
Thanks Buu - yes I definitely agree Transaction Script can quickly become unmanagable, but I'd also like to avoid creating a dependency between my Model classes. I could duplicate the logic in my Model classes, but that defeats the reason for avoiding Transaction Script in the first place.
Benco
A: 

Depends on complexity. As Buu says, it depends on your app complexity. TS is quick and dirty - it may be all you need for this particular job. Having said that, IME, the more code you write to solve an immediate problem means that code gets bedded in to the app and increases your re-factoring overhead at a later stage - which in turn decreases the likelihood of undertaking that task. Long term, it could make your code messy.

I wouldn't add the method to the User - it's not User "behaviour". Does an Alert qualify as a domain object in it's own right? I think I'd probably make a model for each, and co-ordinate the updates via a service layer (as mentioned by Ray) rather than coupling the classes directly. That way, your View can access the Alerts model directly and display whatever it's state is relative to the current user record.

sunwukung
For the sake of the example, yes Alert is also a Domain object and has it's own related Table Data Gateway etc. It's not so much a concern of Views - the business logic I'm talking about is a discrete set of steps that needs to run immediately after User records have been written to the database.
Benco