關(guān)于面向過程和面向?qū)ο缶幊讨g的區(qū)別這里不多說,簡單看了一個例子,如何解決把大象裝進冰箱這個問題?
面向過程方案:
第一步.打開冰箱;第二步.把大象放進冰箱;第三步,關(guān)上冰箱;這個方案看上去沒什么毛病,簡單明了,當然第二步可以拆分的更細,拆成更多小步驟!用代碼簡單演示如下:
<?php
//1.打開冰箱
function openFridge($fridge)
{
echo "打開冰箱:" . $fridge['name'];
}
//2.放置大象
function placeElephant($elephant, $fridge)
{
if ($elephant['weight'] > $fridge['width']) {
echo "大象太大了!";
return false;
}
echo "把{$elephant['name']}放進去:" . $fridge['name'];
return true;
}
//3.關(guān)上冰箱
function closeFridge($fridge)
{
echo "關(guān)掉冰箱:" . $fridge['name'];
}
然后實際操作的代碼:
$fridge = [
'name' => '西門子冰箱',
'width' => 20,
'height' => 50,
];
$elephant = [
'name' => '非洲大象',
'weight' => 100,
];
//三步走
openFridge($fridge);
placeElephant($elephant, $fridge);
closeFridge($fridge);
面向過程編程典型的做法就是定義一大堆函數(shù),一個函數(shù)干一件事,然后依次調(diào)用各個函數(shù)完成一個功能.優(yōu)點也有,比如簡單省事,缺點也很多,比如項目大了之后維護是噩夢!
面向?qū)ο蠓桨?
首先,得有2個類,一個是大象類:
//大象類
class Elephant
{
private $name;
private $weight;
public function __construct($name, $weight)
{
$this->name = $name;
$this->weight = $weight;
}
....
}
另一個是冰箱類:
class Fridge
{
private $name;
private $width;
public function __construct($name, $width)
{
$this->name = $name;
$this->width = $width;
}
public function open()
{
echo "打開{$this->name}冰箱";
}
public function close()
{
echo "關(guān)閉{$this->name}冰箱";
}
public function store($something)
{
echo "放置{$something}";
}
}
實際操作的時候代碼:
$e = new Elephant('非洲大象', 12);
$f = new Fridge('西門子冰箱', 25);
$f->open();
$e->store($e);
$f->close();
當然這里還有一點小疑問,那就是大象放進冰箱這個操作是屬于哪個對象?是冰箱的功能,還是大象的功能?換句話說是大象自己走進冰箱,還是大象被放進冰箱呢?很多時候,這2種方案都能實現(xiàn)你所需要的功能,那就得結(jié)合實際情況分析了!
換一種思路,假如說,我們定義冰箱有一個功能就是放東西,但是這個東西必須滿足一定條件,比如說讓對象自己選擇采用何種方式放進冰箱等等,這時候我們可以定義一個接口:
interface Fridgeable
{
public function intoFridge();
}
然后讓需要放進冰箱的對象實現(xiàn)這個接口:
class Elephant implements Fridgeable
{
....
//實現(xiàn)接口
public function intoFridge()
{
echo "大象飛進了冰箱";
}
}
這時候冰箱類就可以這樣寫:
...
public function store(Fridgeable $fridgeable)
{
$this->open();
$fridgeable->intoFridge();
$this->close();
}
...
這時候操作就變成:
$e = new Elephant('非洲大象', 12);
$f = new Fridge('西門子冰箱', 25);
$f->store($e);
假如這時候還有一直兔子也要放進冰箱,我們只需要讓這個兔子也實現(xiàn)這個接口即可:
class rabbit implements Fridgeable
{
....
//實現(xiàn)接口
public function intoFridge()
{
echo "兔子鉆進了冰箱";
}
}
而這種設(shè)計思想就叫依賴注入,又叫控制反轉(zhuǎn).冰箱只要定義好一個接口,所有想放進冰箱的對象只要實現(xiàn)這個接口就可以了,這樣我們就不用在冰箱里面寫一大堆代碼,實現(xiàn)了解耦和擴展性!
好啦,就說這么多了,如果不恰當?shù)牡胤秸堉刚?