如何改进我的构图模式代码?

时间:2012-05-17 20:46:40

标签: php oop

我正在尝试构建一个简单的合成模式样本。基本上输出将是每个部门员工的总智能。我创建了3种类型的员工和2个部门。请参阅以下代码:

员工类

abstract class Employee {

    function addEmployee(Employee $employee){

    }

    function removeEmployee(){

    }

    abstract function showIntelligent();

}

小兵班

class Minion extends Employee {

       function showIntelligent(){
          return '100';
    } 


}

经理类

class Manager extends Employee {

    function showIntelligent(){
           return '150';
    } 



}

销售部门课程

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;
    }

}

设计系类

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;
    }


}

我的索引

    $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();

似乎我必须使用大量代码来添加新员工。这是一个好习惯吗?无论如何改进它?谢谢你的任何建议。

2 个答案:

答案 0 :(得分:1)

您可以更改addEmployee()方法以获取整数计数参数。

这可以减少7行代码到以下内容:

$DesignDpt->addEmployee(new Minion(), 7);

答案 1 :(得分:1)

我有很多评论 - 其中一些已被提及。

1)拥有一个包含Minion和Manager子类的Employee类并不是一个好主意。这里的问题是Minions可以被提升为Managers,并且不应该要求你丢弃旧对象并用新对象替换它们。相反,为Employee提供一个具有“角色”实例变量的类,其中包含MinionRole或ManagerRole。使用此设计,您可以替换角色而无需替换整个Employee对象。实际上,根据您到目前为止所描述的内容,您根本不需要角色 - 只是智能的实例变量。

2)部门类不应该从Employee继承。部门不是员工,不能用作员工的替代品。创建一个名为Department的新类。你真的需要子类吗?是否足以拥有每个部门都有名称的部门实例(销售,设计等?)如果添加会计部门,您是否真的想要修改,重新编译,重新包装和重新部署应用程序?

子类仅在子类具有不同行为时才有用。在您的情况下,子类具有相同的行为或足够接近,使得简单的实例变量可以使其工作。不要过于兴奋继承。继承不是所有问题的答案,应该谨慎使用。 Smalltalk编程语言的创建者Alan Kay和创造“面向对象”这个术语的人从不喜欢继承的概念,只是不情愿地接受它以允许更好的代码共享。