一、面向对象编程的6大设计原则
单一职责原则——类要职责单一,一个类只需要做好一件事情。
里氏替换原则——子类可以扩展父类的功能,但不能改变父类原有的功能(可以实现父类的抽象方法和增加自己特有的方法,不要覆盖父类的非抽象方法)。
依赖倒置原则——-面向接口编程:只需关心接口,不需要关心实现。
接口隔离原则——-建立单一接口,尽量细化接口,接口中的方法尽量少。低耦合高内聚。
最少知识原则——-一个类对自己依赖的类知道的越少越好,两实体间最好不交互或少交互。
开闭原则——-对扩展开放,对修改关闭。
二、6大设计模式和应用场景
6大设计模式:单例、工厂、观察者、适配器、策略、装饰器
单例:单例设计模式常应用于数据库类设计,采用单例模式,只连接一次数据库,防止打开多个数据库连接。
工厂:常用于根据输入参数的不同或者应用程序配置的不同来创建一种专门用来实例化并返回其对应的类的实例。
观察者:一模式允许某个类观察另一个类的状态,当被观察的类状态发生改变的时候,观察类可以收到通知并且做出相应的动作;观察者模式为您提供了避免组件之间紧密耦。
适配器:老代码接口不适应新的接口需求,或者代码很多很乱不便于继续修改,或者使用第三方类库。例如:php连接数据库的方法:mysql,,mysqli,pdo,可以用适配器统一
策略:将一组特定的行为和算法封装成类,以适应某些特定的上下文环境。例如:一个电商网站系统,针对男性女性用户要各自跳转到不同的商品类目,并且所有广告位展示不同的广告
装饰器:动态地添加修改类的功能。
<?php
/**
* 单例模式
*/
class Database
{
// We need a static private variable to store a Database instance.
private static $instance;
// Mark as private to prevent it from being instanced.
private function __construct()
{
// Do nothing.
}
private function __clone()
{
// Do nothing.
}
public static function getInstance()
{
if (!(self::$instance instanceof self)) {
self::$instance = new self();
}
return self::$instance;
}
}
$a =Database::getInstance();
$b =Database::getInstance();
// true
var_dump($a === $b);
<?php
/*
工厂模式
*/
interface InterfaceShape
{
function getArea();
function getCircumference();
}
/**
* 矩形
*/
class Rectangle implements InterfaceShape
{
private $width;
private $height;
public function __construct($width, $height)
{
$this->width = $width;
$this->height = $height;
}
public function getArea()
{
return $this->width* $this->height;
}
public function getCircumference()
{
return 2 * $this->width + 2 * $this->height;
}
}
/**
* 圆形
*/
class Circle implements InterfaceShape
{
private $radius;
function __construct($radius)
{
$this->radius = $radius;
}
public function getArea()
{
return M_PI * pow($this->radius, 2);
}
public function getCircumference()
{
return 2 * M_PI * $this->radius;
}
}
/**
* 形状工厂类
*/
class FactoryShape
{
public static function create()
{
switch (func_num_args()) {
case 1: return new Circle(func_get_arg(0));break;
case 2: return new Rectangle(func_get_arg(0), func_get_arg(1));break;
default: break;
}
}
}
$rect =FactoryShape::create(5,5);
// object(Rectangle)#1 (2) { ["width":"Rectangle":private]=> int(5) ["height":"Rectangle":private]=> int(5) }
var_dump($rect);
echo "<br>";
// object(Circle)#2 (1) { ["radius":"Circle":private]=> int(4) }
$circle =FactoryShape::create(4);
var_dump($circle);
<?php
/*
观察者模式
*/
// 可被观察者接口
interface InterfaceObservable
{
function addObserver($observer);
function removeObserver($observer_name);
}
// 观察者接口
interface InterfaceObserver
{
function onListen($sender, $args);//$sender被观察者对象,$args被观察内容
function getObserverName();
}
// 可被观察者抽象类
abstract class Observable implements InterfaceObservable
{
protected $observers = array();
public function addObserver($observer)
{
if ($observer instanceof InterfaceObserver)
{
$this->observers[] = $observer;
}
}
public function removeObserver($observer_name)
{
foreach ($this->observers as $index => $observer)
{
if ($observer->getObserverName() === $observer_name)
{
array_splice($this->observers, $index, 1);
return;
}
}
}
}
// 观察者抽象类
abstract class Observer implements InterfaceObserver
{
protected $observer_name;
function getObserverName()
{
return $this->observer_name;
}
function onListen($sender, $args)
{
}
}
// 模拟一个可以被观察的类
class A extends Observable
{
public function addListener($listener)
{
foreach ($this->observers as $observer)
{
$observer->onListen($this, $listener);
}
}
}
// 模拟一个观察者类
class B extends Observer
{
protected $observer_name = 'B';
public function onListen($sender, $args)
{
var_dump($sender);
echo "<br>";
var_dump($args);
echo "<br>";
}
}
// 模拟另外一个观察者类
class C extends Observer
{
protected $observer_name = 'C';
public function onListen($sender, $args)
{
var_dump($sender);
echo "<br>";
var_dump($args);
echo "<br>";
}
}
$a = new A();
// 注入观察者
$a->addObserver(new B());
$a->addObserver(new C());
// 可以看到观察到的信息
$a->addListener('D');//A对象(B,C对象在其数组中),D
// 移除观察者
$a->removeObserver('B');
$a->addListener('D');//object(B,C对象在其数组中),D
// 打印的信息:
// object(A)#1 (1) { ["observers":protected]=> array(2) { [0]=> object(B)#2 (1) { ["observer_name":protected]=> string(1) "B" } [1]=> object(C)#3 (1) { ["observer_name":protected]=> string(1) "C" } } }
// string(1) "D"
// object(A)#1 (1) { ["observers":protected]=> array(2) { [0]=> object(B)#2 (1) { ["observer_name":protected]=> string(1) "B" } [1]=> object(C)#3 (1) { ["observer_name":protected]=> string(1) "C" } } }
// string(1) "D"
// object(A)#1 (1) { ["observers":protected]=> array(1) { [0]=> object(C)#3 (1) { ["observer_name":protected]=> string(1) "C" } } }
// string(1) "D"
<?php
/*
装饰器模式
*/
interface Decorator{
public function display();
}
class XiaoFang implements Decorator{
private $name;
public function __construct($name){
$this->name = $name;
}
public function display(){
echo "我是".$this->name.",我出门了!!!"."<br>";
}
}
class Finery implements Decorator{
private $component;
public function __construct(Decorator $component){
$this->component=$component;
}
public function display(){
$this->component->display();
}
}
class Shoes extends Finery{
public function display(){
echo "穿上鞋子"."<br>";
parent::display();
}
}
class Skirt extends Finery{
public function display(){
echo "穿上裙子"."<br>";
parent::display();
}
}
class Fire extends Finery{
public function display(){
echo "出门前先整理头发"."<br>";
parent::display();
echo "出门后再整理一下头发"."<br>";
}
}
$xiaofang=new XiaoFang("小芳");
$shoes=new Shoes($xiaofang);
$skirt=new Skirt($shoes);
$fire=new Fire($skirt);
$fire->display();
// 输出结果:
// 出门前先整理头发
// 穿上裙子
// 穿上鞋子
// 我是小芳,我出门了!!!
// 出门后再整理一下头发
<?php
/*
策略模式
*/
interface clothesAction{
public function display();
}
class ShowBoyClothes implements clothesAction{
public function display(){
echo "There are many boy clothes<br>";
}
}
class ShowGirlClothes implements clothesAction{
public function display(){
echo "There are many girl clothes<br>";
}
}
class ShowPeopleClothes{
private $show;
public function showClothes(){
$this->show->display();
}
public function setClothes(clothesAction $clothes){
$this->show = $clothes;
}
}
class ShowPersonClothes extends ShowPeopleClothes{
}
// Test Case
$p = new ShowPersonClothes();
/* 设置男装 */
$p->setClothes(new ShowBoyClothes());
$p->showClothes();
/* 设置女装 */
$p->setClothes(new ShowGirlClothes());
$p->showClothes();
<?php
/*
适配器模式
*/
//1、源
abstract class Toy
{
public abstract function openMouth();
public abstract function closeMouth();
}
class Dog extends Toy
{
public function openMouth()
{
echo "Dog open Mouth<br>";
}
public function closeMouth()
{
echo "Dog close Mouth<br>";
}
}
class Cat extends Toy
{
public function openMouth()
{
echo "Cat open Mouth<br>";
}
public function closeMouth()
{
echo "Cat close Mouth<br>";
}
}
//2、目标角色:红枣遥控公司+绿枣遥控公司
interface RedTarget
{
public function doMouthOpen();
public function doMouthClose();
}
interface GreenTarget
{
public function operateMouth($type = 0);
}
//3、适配器代码:红枣遥控公司+绿枣遥控公司
class RedAdapter implements RedTarget
{
private $adaptee;
function __construct(Toy $adaptee)
{
$this->adaptee = $adaptee;
}
public function doMouthOpen()
{
$this->adaptee->openMouth();
}
public function doMouthClose()
{
$this->adaptee->closeMouth();
}
}
class GreenAdapter implements GreenTarget
{
private $adaptee;
function __construct(Toy $adaptee)
{
$this->adaptee = $adaptee;
}
public function operateMouth($type = 0)
{
if ($type) {
$this->adaptee->openMouth();
} else {
$this->adaptee->closeMouth();
}
}
}
//4、测试用例
class testDriver
{
public function run()
{
//实例化一只狗玩具
$adaptee_dog = new Dog();
echo "给狗套上红枣适配器<br>";
$adapter_red = new RedAdapter($adaptee_dog);
//张嘴
$adapter_red->doMouthOpen();
//闭嘴
$adapter_red->doMouthClose();
echo "给狗套上绿枣适配器<br>";
$adapter_green = new GreenAdapter($adaptee_dog);
//张嘴
$adapter_green->operateMouth(1);
//闭嘴
$adapter_green->operateMouth(0);
}
}
$test = new testDriver();
$test->run();
//结果:
// 给狗套上红枣适配器
// Dog open Mouth
// Dog close Mouth
// 给狗套上绿枣适配器
// Dog open Mouth
// Dog close Mouth
适配器模式问题的始末详见:https://www.cnblogs.com/DeanChopper/p/4770572.html