Best Practices recommend setting the new method as protected and using instead static new... methods to mitigate the lack of method overloading.
So I use this pattern as explained here
But static methods are not inherited.
So we have to define for each sub class the static construct and the static new... methods.
Therefore we lose some of inheritance's benefits.
I had a look on system classes hoping to find a better solution but what I saw did not really help me :
- some respect the static new pattern and declare the methods in the sub classes
- some just use the instance new without protecting it
- some use the mother class as a "class factory", like SalesFormLetter
static SalesFormLetter construct(DocumentStatus document,
boolean getParmId = true)
{
switch(document)
{
case DocumentStatus::Confirmation : return new SalesFormLetter_Confirm (getParmId);
case DocumentStatus::PickingList : return SalesFormLetter_PickingList::construct(getParmId);
case DocumentStatus::PackingSlip : return new SalesFormLetter_PackingSlip (getParmId);
case DocumentStatus::ProjectPackingSlip : return new SalesFormLetter_PackingSlipProject(getParmId);
case DocumentStatus::Invoice : return new SalesFormLetter_Invoice (getParmId);
case DocumentStatus::ProjectInvoice : return new SalesFormLetter_InvoiceProject (getParmId);
default : throw error(strfmt("@SYS19306",funcname()));
}
throw error(strfmt("@SYS19306",funcname()));
}
So I am wondering if there is a better solution, and if not what would be the best among these ?
A better solution to object construction?
Well, the new have to go somewhere, and putting a lot of new in the client code is fragile and inflexible. So go with the class "factories" especially for related classes.
Two options:
Make new protected. Make a construct for each sub-class, put the factory construct in the base class calling the sub-class constructors. But anyone can then call the sub-class construct method.
Make new public. Don't make a construct for each sub-class, put factory the construct in the base class, new'ing the sub-classes. The new can't be protected as the base class does not descend from the sub-class.
Whether or not you go with 1 or 2 is your choice, you end up with exposing the sub-class constructor. Personally I prefer option 2, as it is the least hassle.
Advice: make your object dependencies explicit using arguments to new. This will complicate your factories, but that is okay as it moves the complexity from your client code. Setter methods (parm methods) is evil, but is needed for RunBase because the it is required by the batch system.
Also go see what Uncle Bob writes.
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