I'm currently rebuilding a specialised ticket system at work (mainly used to support people with faults in remote sensing hardware...). Anyway, I was wondering whether doing lots of workflow type activity in an object's constructor is a good idea.
For example, there is currently this:
$ticket = new SupportTicket(
$customer,
$title,
$start_ticket_now,
$mail_customer
);
as soon as the object is created, it'll put a row into a database, go and mail the customer a confirmation e-mail, possibly send a text message to the nearest technician, etc..
Should a constructor be firing off all that work, or something more like the following?
$ticket = new SupportTicket($customer, $title);
$customer->confirmTicketMailed($ticket);
$helpdesk->alertNewTicket($ticket);
If it helps, the objects are all based on the ActiveRecord style.
I guess it may be a matter of opinion, but what do you think is the best thing to do?
If the constructor does all that work then the constructor knows about many other domain objects. This creates a dependency problem. Should the ticket
really know about the Customer
and the HelpDesk
? When new features are added, isn't it likely that new domain objects will be added to the workflow, and doesn't that mean that our poor ticket
will have to know about an ever increasing population of domain objects?
The problem with spiderwebs of dependency like this is that a source code change to any one of the domain object will have an impact upon our poor ticket
. The ticket
will have so much knowledge of the system that no matter what happens, the ticket
will be involved. You will find nasty if
statements gathering inside that constructor, checking the configuration database, and the session state, and so many other things. The ticket
will grow to become a god class.
Another reason I dislike constructors that do things is that it makes the objects around them very hard to test. I like to write lots of mock objects. When I write a test against the customer
I want to pass it a mocked out ticket
. If the constructor of ticket
controls the workflow, and the dance between customer
and other domain objects, then it is unlikely that I will be able to mock it out to test the customer
.
I suggest you read The SOLID Principles, a paper I wrote several years back about managing dependencies in object oriented designs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With