设计模式
来源:互联网 发布:魔兽争霸3 mac 编辑:程序博客网 时间:2024/06/05 09:21
一、设计模式的概念
设计模式:针对特定的问题提出的一中解决方案,和平台、语言无关。
作用:
- 更好的理解面向对象的思想
- 使我们的代码更加的优雅
使我们的代码更加容易扩展和复用
面向对象的一些原则:
高内聚、低耦合
- 对扩展开放,对修改封闭(开闭原则)
- 单一职责(一个类的功能应该单一)
二、常见的设计模式
单例
单例就是一个类只实例化一个对象
写法:
- 私有的构造
- 私有的克隆
- 私有的静态属性
- 公有的静态方法
class Dog{ //5 私有的对象成员 protected static $dog; //1. 把构造函数私有化 protected function __construct() {} //2 把clone私有化 protected function __clone() {} //3 反序列化方法__wakeup私有化 protected function __wakeup() {} //4 自己定义公有的方法产生对象 public static function getInstance() { // 如果没有创建对象,self::$dog为空,则创建对象 if (self::$dog == null) { self::$dog = new self(); } return self::$dog; }}$dog1 = Dog::getInstance(); //new Dog();
使用场景
应用只启动一次,连接数据库等耗费资源的类都可以考虑使用单例
简单工厂
把客户端代码和类隔离,统一了对象的创建,修改了类不会影响到客户端的代码
abstract class Calculator implements IOperating{ public $num1; public $num2; public abstract function operate();}class Add extends Calculator{ public function operate() { return $this->num1 + $this->num2; }}//核心类class SimpleFactory{ public static function create($operator) { switch($operator) { case '+': return new Add(); break; case '-': break; } }}// 客户端代码//所有对象的创建,都通过工厂$obj = SimpleFactory::create('+');$obj->num1 = 10;$obj->num2 = 20;echo $obj->operate();
工厂方法
与简单工厂不同,工厂类不再创建对象,把实例化对象的任务交给了子类
优点:解决了工厂不容易扩展的缺陷
缺点:客户端的代码负载
abstract class Calculator{ public $num1; public $num2; public abstract function operate();}class Add extends Calculator{ public function operate() { return $this->num1 + $this->num2; }}class Sub extends Calculator{ public function operate() { return $this->num1 - $this->num2; }}//改进class SimpleFactory{ public static function create($className) { return new $className(); }}//客户端代码//所有对象的创建,都通过工厂$addObj = AddFactory::create();$addObj->operate();SimpleFactory::create('Add');
观察者模式
- 一个对象观察另一个对象,当被观察对象的状态发生变化时,观察者对象可以收到通知做出相应的改变。观察者模式提供了解耦观察者和被观察者两个类之间的解耦。
- 适用于:一个对象发生改变时,通知另外依赖它的对象,依赖对象做相应的改变
interface AbstractObserver{ public function upate($info=null);//通知的消息}class Student implements AbstractObserver { public function update($info = null) { echo "好好学习<br/>"; }}//抽象的被观察者interface AbstractSubject{ public function attach(AbstractObserver $obserer); public function detach(AbstractObserver $obserer); public function notify();}//被观察者class Subject implements AbstractSubject{ protected $obserers = []; public function __construct() { } //添加观察者 public function attach(AbstractObserver $obserer) { $this->obserers[] = $obserer; } //删除观察者 public function detach(AbstractObserver $obserer) { //返回键值 $key = array_search($obserer, $this->obserers); if ($key !== false) { unset($this->obserers[$key]); } } //通知观察者 public function notify() { foreach ($this->obserers as $key => $value) { $value->update();//通知 } }}
适配器模式
可以将一个系统的接口转换成客户希望的接口,使得原本不兼容系统可以一块工作
使用场景:
- 使用了一个接口经常会发生变化的第三方库
- 旧系统的接口和新系统的不兼容,但旧系统比较复杂,不容易修改
//服务器端提供json//{'name':'tom','age':18,'sex':'男'} json//['name'=>'tom','age'=>18,'sex'=>'男']class Server{ public function json() { return json_encode(['name'=>'tom','age'=>18,'sex'=>'男']); }}//需要转换的接口方法interface IAdaper{ //转换方法 public function json2Aarray();}//适配器类class Adapter implements IAdaper{ //1 包含一个server对象 protected $server; public function __construct($server) { $this->server = $server; } //2 实现接口方法 public function json2Aarray() { var_dump($this->server->json()); //将json串转换为数组,第二个参数必须为true return json_decode($this->server->json(),true); }}//客户端代码class Client{ public function test($data) { foreach ($data as $key => $value) { var_dump($value); } }}//客户端代码$server = new Server();//转换器$adapter = new Adapter($server);//客户端$client = new Client();var_dump($adapter->json2Aarray());$client->test($adapter->json2Aarray());
策略模式
在不同情况会使用不同算法,要解耦算法对对象的影响,可以使用策略模式
//策略模式interface ISalary{ public function computeSalary();//计算工资的方法}class Manager implements ISalary{ public function computeSalary() { echo "基本工资+补贴+效益<br/>"; }}class Teacher implements ISalary{ public function computeSalary() { echo "基本工资+补贴<br/>"; }}//环境类class Context{ protected $strategy;//策略 //1 设置策略 public function setStrategy(ISalary $strategy) { $this->strategy = $strategy; } //调用对象实现策略 public function compute() { $this->strategy->computeSalary(); }}//客户端代码$teacher = new Teacher();$manager = new Manager();$context = new Context();$context->setStrategy($teacher);$context->compute();
门面设计模式
使用场景:
- 给复杂的子系统提供一个简单的接口
提高子系统的独立性
优点:对客户屏蔽了子系统,因此减少了客户处理对象的数目,并且使得子系统使用起来更加方便
- 实现了子系统与客户之间的松耦合关系
//门面设计模式class SystemA{ public function demo1() { echo "A:demo1<br/>"; }}class SystemB{ public function demo2() { echo "B:demo2<br/>"; }}class SystemC{ public function demo3() { echo "C:demo3<br/>"; }}class Facade{ protected $systemA; protected $systemB; protected $systemC; public function __construct() { $this->systemA = new SystemA(); $this->systemB = new SystemB(); $this->systemC = new SystemC(); } //新接口 public function demo() { $this->systemA->demo1(); $this->systemB->demo2(); $this->systemC->demo3(); }}
依赖注入/控制反转(DI)
依赖注入(Dependency Injection)
控制反转(Inversion of Control)
当一个类的实例需要另一个类的实例协助时,在传统的程序设计过程中,通常由调用者来创建被调用者的实例。而采用依赖注入的方式,创建被调用者的工作不再由调用者来完成,因此叫控制反转,创建被调用者的实例的工作由IOC容器来完成,然后注入调用者,因此也称为依赖注入。
interface IRunning{ public function run();//交通工具的运行方式}class Bus implements IRunning{ public function run() { echo "坐公交"; }}class Ofo implements IRunning{ public function run() { echo "骑自行车"; }}class Person{ public $name; public function __construct($name) { $this->name = $name; } public function goHome($tool)//person依赖于注入的对象 { echo $this->name; $tool->run(); echo "回家<br/>"; }}$wzy = new Person('Tom');$wzy->goHome(new Bus());
阅读全文
0 0
- 设计模式
- 设计模式
- 设计模式
- 设计模式
- 设计模式
- 设计模式
- 设计模式~~~~~~~~~~
- 设计模式
- 设计模式
- 设计模式
- 设计模式
- 设计模式
- 设计模式
- 设计模式
- 设计模式
- 设计模式
- 设计模式
- 设计模式
- Tab
- hiveserver2 后台运行
- ViewPager无限轮播
- CHAR_LENGTH(str)函数
- Java中的hashcode方法
- 设计模式
- SQL注入limit用法
- 使用依赖添加无线轮播加按钮
- Springboot Dubbo ZooKeeper整合
- OC : NSData (二进制数据流)
- 欢迎使用CSDN-markdown编辑器
- android utils
- ECMAScript 与 JavaScript的联系 以及为什么会有浏览器兼容的问题?
- 使用 ortp 发送原始 H.264 码流