各位好,我看了《大话设计模式》中的组合模式,示例中是建立了三个类:
1、Company抽象类:定义了公司的名称属性name,和一组抽象操作:add remove display
2、ConcreteCompany具体公司类:定义了一个children属性,用来存放子节点,并定义了和面三个方法的实现
3、HRDepartment部门类:ConcreteCompany类一样,只是覆写了方法
2和3都继承自1。
我照示例做了之后,发现用起来好麻烦,于是,我自己建立了一个类:
Company:定义属性name,属性children,和同样的三个操作。
也能同样实现组合模式的效果。
所以,我这样做,有问题吗?我真不知道区别在哪!!!
上我的代码:
class Company {
protected $name; //单位名称,或部门名称
protected $children = array(); //存储子节点
public function __construct($name) { //实例化时传入名称
$this->name = $name;
}
public function add(Company $test) { //添加子节点
$this->children[] = $test;
}
public function display($depth) { //显示结构
echo str_pad('-', $depth, '-', STR_PAD_LEFT).$this->name.'<br />';
foreach($this->children as $child) {
$child->display($depth+1);
}
}
}
$root = new Company('总公司');
$sub1 = new Company('分公司1');
$sub1->add(new Company('部门1'));
$sub1->add(new Company('部门2'));
$root->add($sub1);
$root->display(1);
下面是大话中的代码:
abstract class Company {
protected $name;
public function __construct($name) {
$this->name = $name;
}
public abstract function Add(Company $c);
public abstract function Display($depth);
}
class ConcreteCompany extends Company {
private $children = array();
public function Add(Company $c) {
$this->children[] = $c;
}
public function Display($depth) {
echo str_pad('-', $depth, '-', STR_PAD_LEFT).$this->name.'<br />';
foreach($this->children as $child) {
$child->Display($depth+1);
}
}
}
class HRDepartment extends Company {
public function Add(Company $c) {}
public function Display($depth) {
echo str_pad('-', $depth, '-', STR_PAD_LEFT).$this->name.'<br />';
}
}
$root = new ConcreteCompany('总公司');
$sub1 = new ConcreteCompany('分公司1');
$sub1->Add(new HRDepartment('部门1'));
$sub1->Add(new HRDepartment('部门2'));
$root->Add($sub1);
$root->Display(1);
两种代码显示的结果一样:
-总公司
--分公司1
---部门1
---部门2
请教各位,这两种代码哪种好?理由呢?
------解决思路----------------------
用你的实现有一些缺点:所有增加子部门的方法都是采用相同的构造函数Company(),也就是说构造方式是一样的,当然你这里company只有一个属性name,体现不出问题。事实上总公司与子公司、子公司与部门的构造方式肯定是有差别的。所以你的实现方式就存在这样的问题。而下面的实现就不会,它会采用具体公司的构造方式,而且下面的扩展起来很方便,只要继承Company按照自己的方式并实现其中的方法就可以了。
设计模式我也不是很熟悉,抛砖引玉。。。