我们有三个类,Db,FileSystem,Session;实际业务需求要组合操作这三个类.

一.常规做法

class Db
{
public function read($id)
{ }
} class FileSystem
{
public function writeFile($file)
{ }
} class Session
{
public function setSession($sessionName)
{ }
} // 实际逻辑
class Logic
{
protected $db;
protected $file;
protected $session; public function __construct()
{
$this->db = new Db();
$this->file = new FileSystem();
$this->session = new Session();
} public function handle($id)
{
if ($name = $this->db->read($id)) {
$this->file->writeFile(md5($name) . '.txt');
$this->session->setSession($id);
}
}
} $id = 11;
$client = new Logic();
$client->handle($id);

  

缺点:
Logic内部高度耦合了,Db,FileSystem,Session
如果这三个类的初始化条件变化,则需要修改Logic的构造方法.

二.参数依赖(类型提示,将新建关联类的放入调用处)

修改Logic代码如下:

class Logic
{
protected $db;
protected $file;
protected $session; public function __construct(Db $db, FileSystem $file, Session $session)
{
$this->db = $db;
$this->file = $file;
$this->session = $session;
} public function handle($id)
{
if ($name = $this->db->read($id)) {
$this->file->writeFile(md5($name) . '.txt');
$this->session->setSession($id);
}
}
} $id = 11;
$db = new Db();
$file = new FileSystem();
$session = new Session();
$client = new Logic($db, $file, $session);
$client->handle($id);

  

优点:
实现了解耦

缺点:
业务变动,如果要更改Db类到MySql类或初始化条件变动,代码依然要改动.

ps:大部分的设计模式使用了该解耦方法.

三.容器

1.希望DB类,Session类,FileSystem类“拿来即用”,不用每次繁琐的初始化,比如写$db=new DB(arg1,arg2);这类语句。
2.希望DB等类型的对象是“全局”,在整个程序运行期间,随时可以调用。
3.调用DB等类型的程序员不用知道这个类太多的细节,甚至可以用一个字符串的别名来创建这样一个对象。

能够实现以上目标的就是IOC容器,可以把IOC容器简单的看成一个全局变量,并用关联数组把字符串和构造函数做绑定

// 容器
class Container
{
public $binds = array(); public function bind($abstract, $concreate)
{
$this->binds[$abstract] = $concreate;
} public function make($abstract, $params = [])
{
return call_user_func_array($this->binds[$abstract], $params);
}
} // 绑定或注册
$container = new Container();
$container->bind('db', function () {
return new Db();
});
$container->bind('file', function () {
return new FileSystem();
});
$container->bind('session', function () {
return new Session();
}); // 实际逻辑,容器依赖
class Logic
{
protected $db;
protected $file;
protected $session; public function __construct(Container $container)
{
$this->db = $container->make('db');
$this->file = $container->make('file');
$this->session = $container->make('session');
} public function handle($id)
{
if ($name = $this->db->read($id)) {
$this->file->writeFile(md5($name) . '.txt');
$this->session->setSession($id);
}
}
} $id = 11;
$logic = new Logic($container);
$logic->handle($id);

  

本文参考自:https://www.cnblogs.com/sweng/p/6430374.html

php解耦的三种境界的更多相关文章

  1. 学习Python的三种境界

    前言 王国维在<人间词话>中将读书分为了三种境界:"古今之成大事业.大学问者,必经过三种之境界:'昨夜西风凋碧树,独上高楼,望尽天涯路'.此第一境也.'衣带渐宽终不悔,为伊消得人 ...

  2. zha男/女的三种境界

    本文为chedan贴,谈一谈找对象时渣男/女的三种表现,分别对应三种境界,涉世未深的男生女生可加以小心,自身属于zha类型的可略过本文.    另,本文的恋爱观基于两个原则.一是对象应是从朋友到恋人的 ...

  3. 【转】从框架看PHP的五种境界及各自的薪资待遇

    无意中看到这篇文章,有些触动,作为博客开篇,用来激励自己. 原文地址:点击打开 在撰写此文前首先必须申明的是本人不鄙视任何一种框架,也无意于挑起PHP框架间的战争,更没有贬低某个框架使用者的用意,本文 ...

  4. 转:从框架看PHP的五种境界及各自的薪资待遇(仅限于二三线城市,一线除外)

    在撰写此文前首先必须申明的是本人不鄙视任何一种框架,也无意于挑起PHP框架间的战争,更没有贬低某个框架使用者的用意,本文纯粹个人的看法.你可以认为我无知也好,或者装逼也好,请不要试着在任何情况下,随便 ...

  5. 在ASP.NET MVC中使用Unity进行依赖注入的三种方式

    在ASP.NET MVC4中,为了在解开Controller和Model的耦合,我们通常需要在Controller激活系统中引入IoC,用于处理用户请求的 Controller,让Controller ...

  6. Linux就这个范儿 第15章 七种武器 linux 同步IO: sync、fsync与fdatasync Linux中的内存大页面huge page/large page David Cutler Linux读写内存数据的三种方式

    Linux就这个范儿 第15章 七种武器  linux 同步IO: sync.fsync与fdatasync   Linux中的内存大页面huge page/large page  David Cut ...

  7. ASP.NET MVC中使用Unity进行依赖注入的三种方式

    在ASP.NET MVC中使用Unity进行依赖注入的三种方式 2013-12-15 21:07 by 小白哥哥, 146 阅读, 0 评论, 收藏, 编辑 在ASP.NET MVC4中,为了在解开C ...

  8. Struts中的数据处理的三种方式

    Struts中的数据处理的三种方式: public class DataAction extends ActionSupport{ @Override public String execute() ...

  9. Spring IOC以及三种注入方式

    IOC是spring的最基础部分,也是核心模块,Spring的其他组件模块和应用开发都是以它为基础的.IOC把spring的面向接口编程和松耦合的思想体现的淋漓尽致. IOC概念 IOC(Invers ...

随机推荐

  1. C# 正则表达式判断IP,URL等及其解释

    C# 正则表达式判断IP,URL等及其解释 判断IP格式方法: public static bool ValidateIPAddress(string ipAddress) { Regex valid ...

  2. HTML布局相关的CSS样式属性

    # 转载请留言联系 注意,样式属性是写进CSS里面的. 布局常用样式属性: width 设置元素(标签)的宽度,如:width:100px; height 设置元素(标签)的高度,如:height:2 ...

  3. javascript:入门笔记

    1:html注释: <html> <body> <script type="text/javascript"> <!-- document ...

  4. KVM(四) I/O 设备直接分配和 SR-IOV

    (4):I/O 设备直接分配和 SR-IOV 本文将分析 PCI/PCIe 设备直接分配(Pass-through)和 SR-IOV, 以及三种 I/O 虚拟化方式的比较. 1. PCI/PCI-E ...

  5. PHP极速开发框架LotusAdmin page版发布

    体验地址及账号如下: 地址    https://page.waytomilky.com/ 账号:admin 密码:123456 LotusAdmin2.0其主要特性包括: 1.基于ThinkPHP5 ...

  6. Burpsuite使用技巧

    在bp任意窗口中,选中需要转码的字符串,按ctrl+b,则可以被转换成base64编码

  7. Codeforces 702D Road to Post Office(模拟 + 公式推导)

    题目链接:http://codeforces.com/problemset/problem/702/D 题意: 一个人要去邮局取东西,从家到达邮局的距离为 d, 它可以选择步行或者开车,车每走 k 公 ...

  8. 36、Django实战第36天:首页功能开发

    1.编辑users.views.py ... class IndexView(View): """ 首页 """ def get(self, ...

  9. Column 1 of table 'xxx' cannot be converted from type 'varchar(33)' to type 'varchar(11)'

    mysql主从同步失败.错误日志如下. Column 1 of table 'xxx' cannot be converted from type 'varchar(33)' to type 'var ...

  10. 6.5(java学习笔记)其他流(字节数组流,数据流,对象流,打印流)

    一.字节数组流 之前使用输入输出流的操作的对象是文件,而这里字节数组流操作的对象是内存,内存可以看做是一个字节数组. 使用字节数组流读写就可以看做是从内存A到内存B的读写,对象时内存即字节数组. 1. ...