Reputation: 4253
I have classes MonthTimeCard and MonthReport. They use same input field for choosing month, so the validation is the same and initialisation is the same.
class MonthTimeCard {
private function setPrivateVarsByUserInput()
{
$this->month_from_input = '2015-09';
$this->date_from = '2015-09-01';
$this->date_to = '2015-09-30';
// lets say those 3 values are formated, validated and returned as array from MonthUserInput class.
// but I have to repeat code in my both classes to initialize them
// I could have one liner like $this->data = $this->monthUserInput->getInput();
// but current class code will need to call $this->data->[variable] everywhere - not looking very nice,
// because ->data is not usefull here, just extra characters.
}
}
Class MonthReport {
... same initialisation
}
I now just hard coded them but you know assignment will be from return array of MonthUserInput class which will validate. There is only one user input field which gets string like '2015-09' and MonthUserInput class will add first day and last day of month.
I could avoid this if I would use inheritance but I have read that should avoid and some even say that it should be removed from OOP.
http://blogs.perl.org/users/sid_burn/2014/03/inheritance-is-bad-code-reuse-part-1.html
With inheritance I would simply in do validating and setting user input in parent class and so no duplication.
How should I do this now? Of course its just 3 variables in this example, I plan to have 5, its not much, but still its duplication and with inheritance there would not be duplication in this case.
Update
I would like to see explanation which I could use to explain to anybody who do not agree that inheritance would be bad to this situation. For example I discussed with one experienced programmer and he does not see a problem here to use inheritance for code reuse. I just said there is lot on internet telling that use composition, but that was not good argument for this situation.
For example:
Favor composition over inheritance. If two classes don't have an "is a" relationship, then it should never be necessary to use inheritance to achieve code reuse. Never.
this would not be a good argument for some people. They can ask - who invented those rules and why? They do not see a problem by breaking this rule.
Upvotes: 0
Views: 91
Reputation: 10084
Inheritance is a powerful tool and can achieve code reuse, however it brings potential problems of its own and should be used appropriately. Because subclasses depend on the superclass implementation, inheritance breaks encapsulation and can make code more fragile and difficult to maintain.
Achieve the discipline to use inheritance only when there really is a "IS A" relationship, eg. a PreferredClient IS A Client ... or ... a MountainBike IS A Bike. If you are designing a class that doesn't achieve an IS A relationship with an intended superclass, then don't use inheritance.
You can achieve a similar degree of code reuse by using composition instead of inheritance. Instead of making a subclass, incorporate the intended superclass as an attribute of your class. This allows you to delegate method calls to the contained instance and achieve code reuse.
For your code example, a suggested code decomposition might be this:
class MonthTimeCard {
Month myMonth;
MonthTimeCard(Month month) { myMonth = month; }
private function setPrivateVarsByUserInput() {
// calls to myMonth
}
}
Class MonthReport {
// calls to myMonth
}
Class Month {
$this->month_from_input = ...
$this->date_from = ...
$this->date_to = ...
}
Upvotes: 2
Reputation: 6079
If MonthTimeCard
and MonthReport
do not logically extend each other (such as Dog
and Cat
are sub types of Animal
), its not a good idea to use inheritance here anyway.
Besides that, if you do the same validation at multiple locations, you could introduce a standalone DateValidator
class and use that whenever required.
public class DateValidator {
public static boolean validate(final String dateString) {
return ...; // TODO: Validate user input here
}
}
Upvotes: 1