我的github部落格 https://zgxxx.github.io/
設計模式六大原則
開放封閉原則:一個軟體實體如類、模組和函式應該對擴充套件開放,對修改關閉。
里氏替換原則:所有引用基類的地方必須能透明地使用其子類的物件.
依賴倒置原則:高層模組不應該依賴低層模組,二者都應該依賴其抽象;抽象不應該依賴細節;細節應該依賴抽象。
單一職責原則:不要存在多於一個導致類變更的原因。通俗的說,即一個類只負責一項職責。
介面隔離原則:客戶端不應該依賴它不需要的介面;一個類對另一個類的依賴應該建立在最小的介面上。
迪米特法則 :一個物件應該對其他物件保持最少的瞭解。
單例模式 (建立設計模式)
要點:只有一個例項,作為物件的建立模式,單例模式確保某一個類只有一個例項,而且自行例項化並向整個系統提供這個例項。
常見: 資料庫連線,日誌錯誤記錄(多種用途使用多種模式)
<?php
/**
* 單例模式
*/
class Singleton
{
/**
* @var self[儲存例項]
*/
private static $instance;
/**
* @var
*/
public $mix;
/**
* return self instance [建立一個用來例項化物件的方法]
*/
public static function getInstace()
{
var_dump(isset(self::$instance));
if (!self::$instance instanceof self) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Singleton constructor.建構函式為private,防止建立物件
*/
private function __construct()
{
echo "例項初始化了";
}
private function __clone()
{
// TODO: Implement __clone() method.
trigger_error('Clone is not allowed!');
}
}
// @Test
$firstSingle = Singleton::getInstace();
$secondSingle = Singleton::getInstace();
$firstSingle->mix = 'one';
//一開始mix是賦值‘one',所以列印出one
print_r($firstSingle->mix);
//由於getInstace該方法保證了Singleton類只能有一個例項,不會再重新new,minx依然用firstSingle的,mix被改變成’two‘
$secondSingle->mix = 'two';
print_r($firstSingle->mix);
print_r($secondSingle->mix);
列印結果:bool(false) 例項初始化了bool(true) onetwotwo
簡單工廠模式 (建立設計模式)
要點:可以根據引數的不同返回不同類的例項。簡單工廠模式專門定義一個類來負責建立其他類的例項,被建立的例項通常都具有共同的父類。
<?php
/**
* 簡單工廠模式
*/
interface SystemFactory
{
public function createSystem($type);
}
class MySystemFactory implements SystemFactory
{
// 實現工廠方法
public function createSystem($type)
{
switch ($type) {
case 'Mac':
return new MacSystem();
case 'Win':
return new WinSystem();
case 'Linux':
return new LinuxSystem();
}
}
}
class MacSystem
{
public function __construct()
{
echo "I am Mac system</br>";
}
}
class WinSystem
{
public function __construct()
{
echo "I am Win system</br>";
}
}
class LinuxSystem
{
public function __construct()
{
echo "I am Linux system</br>";
}
}
//建立系統工廠
$systemObj = new MySystemFactory();
$systemArray = array('Mac','Linux','Win');
foreach ($systemArray as $val) {
$systemObj->createSystem($val);
}
列印結果:
I am Mac system
I am Linux system
I am Win system
工廠模式 (建立設計模式)
要點:此模式中,透過定義一個抽象的核心工廠類,並定義建立產品物件的介面,建立具體產品例項的工作延遲到其工廠子類去完成。這樣做的好處是核心類只關注工廠類的介面定義,而具體的產品例項交給具體的工廠子類去建立。當系統需要新增一個產品,無需修改現有系統程式碼,只需要新增一個具體產品類和其對應的工廠子類,是系統的擴充套件性變得很好,符合物件導向程式設計的開閉原則;
我的理解:
按我平時喜歡玩的籃球遊戲nba2k系列來代入。我來模擬整個NBA聯盟,一開始是沒有球員的,我需要不斷的建立球員,具體就交給Nba底下的各個子類,也就是各個球隊去建立就好
首先有一個球員介面,可以定義球員的投射還有搶籃板球的動作,注意這裡的每個球員暫時只有這兩個動作,生產出來的球員只有投射和搶籃板動作
interface Player{
public function shot();
public function rebound();
}
然後具體到球員自己的動作
class Wade implements Player
{
public function shot()
{
echo "I can shot in middle distance<br>";
}
public function rebound()
{
echo "I can crash the boards <br>";
}
}
class Kobe implements Player
{
public function shot()
{
echo "I can shot the three-point <br>";
}
public function rebound()
{
echo "I can crash the boards <br>";
}
}
定義一個抽象的核心工廠類,也就是整個遊戲有一個建立球員頁面
abstract class NbaFactory{
abstract static function createPlayer();
}
我喜歡熱火,就來操作熱火還有湖人好了,創一個韋德還有科比來玩玩
class HeatTeam extends NbaFactory{
public static function createPlayer()
{
return new Wade();
}
}
class LakersTeam extends NbaFactory{
public static function createPlayer()
{
return new Kobe();
}
}
一切準備好了,就去場上試試能不能打:選人然後投籃搶籃板
$heatPlayer = HeatTeam::createPlayer();
$heatPlayer->shot();
$heatPlayer->rebound();
$lakersPlayer = LakersTeam::createPlayer();
$lakersPlayer->shot();
$lakersPlayer->rebound();
所以工廠模式:不需要NBA這個背後大boss親自去建立球員,只需要定義一個想要建立球員這樣的介面,例項工作就交給子類也就是球隊去建立就行了,當我們想要增加一個自己喜歡的球員來玩,只需要新增一個具體的球員,然後設定他有什麼動作呀,能力呀,再對應你想要他在哪一支隊伍就ok了,這樣就不需要修改現有系統程式碼,系統的擴充套件性變得很好,符合物件導向程式設計的開閉原則
整體程式碼如下:
<?php
/**
* 球員動作
* Interface Player
*/
interface Player{
public function shot();
public function rebound();
}
/**
* 設定韋德投籃以及搶籃板
* Class Wade
*/
class Wade implements Player
{
public function shot()
{
echo "I can shot in middle distance<br>";
}
public function rebound()
{
echo "I can crash the boards <br>";
}
}
/**
* 設定科比投籃以及搶籃板
* Class Kobe
*/
class Kobe implements Player
{
public function shot()
{
echo "I can shot the three-point <br>";
}
public function rebound()
{
echo "I can crash the boards <br>";
}
}
/**
* 整個遊戲NBA具備建立球員這一項功能
* Class NbaFactory
*/
abstract class NbaFactory{
abstract static function createPlayer();
}
/**
* 熱火隊建立了韋德這樣的球員
* Class HeatTeam
*/
class HeatTeam extends NbaFactory{
public static function createPlayer()
{
return new Wade();
}
}
/**
* 湖人隊建立了科比這樣的球員
* Class LakersTeam
*/
class LakersTeam extends NbaFactory{
public static function createPlayer()
{
return new Kobe();
}
}
/**
* 選擇熱火隊,並且測試韋德的動作
*/
$heatPlayer = HeatTeam::createPlayer();
$heatPlayer->shot();
$heatPlayer->rebound();
/**
* 選擇湖人隊,並且測試科比的動作
*/
$lakersPlayer = LakersTeam::createPlayer();
$lakersPlayer->shot();
$lakersPlayer->rebound();
抽象工廠模式 (建立設計模式)
要點:提供一個建立一系列相關或相互依賴物件的介面。注意:這裡和工廠方法的區別是:一系列(多個),而工廠方法只有一個。。在工廠方法模式中,一個具體的工廠負責生產一類具體的產品,即一對一的關係,但是,如果需要一個具體的工廠生產多種產品物件,那麼就需要用到抽象工廠模式了。
我的理解:
工廠模式,一個工廠輔助生產一類具體的產品,就像上邊的例子,球員建立,只有投籃還有搶籃板動作,無論建立韋德科比還是詹姆斯都是隻有這兩種。而抽象工廠,需要生產多種產品,例如下面有兩個遊戲頁面,球衣樣式設定和球鞋樣式設定,這兩個頁面底下是各種包含自己的方法,球衣頁面是主客場球衣設定,球鞋頁面是高低幫和顏色設定。
整體程式碼如下:
<?php
/**
* 球衣樣式設定(客場球衣&主場球衣)
* Interface Uniform
*/
interface Uniform{
public function home();
public function away();
}
/**
* 設定熱火主客場球衣樣式
* Class HeatUniform
*/
class HeatUniform implements Uniform
{
public function home()
{
echo "Set the Heat's uniform with red and white <br>";
}
public function away()
{
echo "Set the Heat's uniform with black and red <br><br>";
}
}
/**
* 球鞋樣式設定(球鞋款式&球鞋主顏色)
* Interface Shoes
*/
interface Shoes{
public function style();
public function color();
}
/**
* 設定熱火主客場球衣樣式
* Class HeatUniform
*/
class HeatShoes implements Shoes
{
public function style()
{
echo "Set the Heat's Shoes'style as height shoes <br>";
}
public function color()
{
echo "Set the Heat's Shoes'color as white <br>";
}
}
/**
* 遊戲球隊設定頁面,包括了服裝設定和球鞋設定
* Class TeamSetting
*/
abstract class TeamSetting{
abstract public static function setUniform();
abstract public static function setShoes();
}
/**
* 熱火隊的球隊設定頁面,有熱火球衣和熱火球鞋設定
* Class HeatSetting
*/
class HeatSetting extends TeamSetting
{
public static function setUniform()
{
return new HeatUniform();
}
public static function setShoes()
{
return new HeatShoes();
}
}
/**
* 操作一:進入熱火隊球衣設定,主場球衣設定為紅白,客場球衣設定為紅黑
*/
$myControl1 = HeatSetting::setUniform();
$myControl1->home();
$myControl1->away();
/**
* 操作二:進入熱火隊球鞋設定,球鞋樣式設定為高幫,顏色設定為白色
*/
$myControl2 = HeatSetting::setShoes();
$myControl2->style();
$myControl2->color();
本作品採用《CC 協議》,轉載必須註明作者和本文連結