軟體重用性取決於類別間耦合度。緊密耦合導致修改一個類別需連鎖修改相關類別。解決之道:定義介面,依賴抽象而非具體實作。
SimpleRouter)直接呼叫介面類別(SimpleRouterFrame)方法。原寫法:
class A { function AMethod(B $b) { $b->BMethod(); } }
改為:
interface I { function Method(); }
class A { function AMethod(I $i) { $i->Method(); } }
class B implements I { function Method() { /* 實作 */ } }
A 僅依賴介面 I,B 實作介面即可替換,隱藏實作細節,實現鬆散耦合。此模式類似 Observer 模式。
interface Calculation { function compute($a, $b); }
class Addition implements Calculation { function compute($a,$b){ return "加法:".($a+$b); } }
class Subtraction implements Calculation { function compute($a,$b){ return "減法:".($a-$b); } }
class Multiplication implements Calculation { function compute($a,$b){ return "乘法:".($a*$b); } }
class Division implements Calculation { function compute($a,$b){ return "除法:".($a/$b); } }
class Modf implements Calculation { function compute($a,$b){ return "取模:".($a%$b); } }
class Coupling implements Calculation {
public $varl = null;
function __construct() { $this->varl = new LazyDog(); }
function compute($a,$b){ return $this->varl->say(); }
}
class LazyDog { function say(){ return "我只為示範耦合模式..."; } }
class Test {
private $one, $two;
function __construct($x,$y){ $this->one=$x; $this->two=$y; }
function display(Calculation $c){ return "運算:".$c->compute($this->one,$this->two); }
}
$t = new Test(96,12);
foreach ([new Addition, new Subtraction, new Multiplication, new Division, new Modf, new Coupling] as $calc) {
echo $t->display($calc) . "
";
}
運算:加法:108 運算:減法:84 運算:乘法:1152 運算:除法:8 運算:取模:0 運算:我只為示範耦合模式...
新增運算類別只需實作 Calculation 介面,Test 完全無需修改,完美體現開放封閉原則。