I am trying to build a simple Composition pattern sample. Basically the output will be each department employees’ total intelligent. I have created 3 types of employee and 2 departments.Please see the following codes:
Employee Class
abstract class Employee {
function addEmployee(Employee $employee){
}
function removeEmployee(){
}
abstract function showIntelligent();
}
Minion class
class Minion extends Employee {
function showIntelligent(){
return '100';
}
}
Manager class
class Manager extends Employee {
function showIntelligent(){
return '150';
}
}
Sales Department Class
class SalesDept extends Employee {
private $_deptEmployee=array();
function addEmployee(Employee $employee){
$this->_deptEmployee[]=$employee;
}
function removeEmployee(){
if(!empty($this->_deptEmployee)){
array_pop($this->_deptEmployee);
}else{
echo 'no employees in Sales Department';
}
}
function showIntelligent() {
$totalInt=0;
foreach ($this->_deptEmployee as $employee){
$totalInt += $employee->showIntelligent();
}
echo 'Total Intelligent of the Sales Department Employees is: '.$totalInt;
}
}
Design Department Class
class DesignDept extends Employee {
private $_deptEmployee=array();
function addEmployee(Employee $employee){
$this->_deptEmployee[]=$employee;
}
function removeEmployee(){
if(!empty($this->_deptEmployee)){
array_pop($this->_deptEmployee);
}else{
echo 'no employees in Design Department';
}
}
function showIntelligent() {
$totalInt=0;
foreach ($this->_deptEmployee as $employee){
$totalInt += $employee->showIntelligent();
}
echo 'Total Intelligent of the Design Department Employees is: '.$totalInt;
}
}
My index
$salesDpt=new SalesDept();
$salesDpt->addEmployee(new Manager());
$salesDpt->addEmployee(new Minion());
$salesDpt->addEmployee(new Minion());
$salesDpt->addEmployee(new GeneralManager());
$salesDpt->showIntelligent();
$DesignDpt=new DesignDept();
$DesignDpt->addEmployee(new Manager());
$DesignDpt->addEmployee(new Manager());
$DesignDpt->addEmployee(new Minion());
$DesignDpt->addEmployee(new Minion());
$DesignDpt->addEmployee(new Minion());
$DesignDpt->addEmployee(new Minion());
$DesignDpt->addEmployee(new Minion());
$DesignDpt->addEmployee(new Minion());
$DesignDpt->addEmployee(new Minion());
$DesignDpt->addEmployee(new GeneralManager());
$DesignDpt->showIntelligent();
It seems like that I have to use lots of codes to add new employees. Is this a good practice? Anyway to improve it? Thanks for any advises.
I have a number of comments – some of which have already been mentioned.
1) Having an Employee class with subclasses of Minion and Manager isn’t a good idea. The problem here is that Minions can be promoted to Managers and that shouldn’t require you to throw away the old objects and replace them with a new ones. Instead, have one class for Employee with a “role” instance variable containing a MinionRole or a ManagerRole. With this design, you can replace the role without replacing the whole Employee object. In fact, from what you’ve described so far, you don’t need roles at all – just an instance variable for the intelligence.
2) The department classes shouldn’t inherit from Employee. A department isn’t an employee and can’t be used as a replacement for an employee. Create a new class called Department. Do you really need subclasses? Would it be enough to have instances of Department where each department has a name (Sales, Design, etc?) Do you really want to have to modify, recompile, repackage and redeploy the application if you add an Accounting department?
Subclassing is only useful when the subclasses have different behavior. In your case, the subclasses have the same behavior or close enough that a simple instance variable would make it work. Don’t get too excited about inheritance. Inheritance isn’t the answer to all problems and should be used carefully. Alan Kay, the creator of the Smalltalk programming language and the person who coined the term “object oriented” never liked the concept of inheritance and only reluctantly accepted it to allow better code sharing.