我们有三个类,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. flask学习:如何从config里载入配置

    代码如下: 1.main.py from flask import Flask from config import DevConfig app=Flask(__name__) app.config. ...

  2. (二)centos7安装zabbix agentd端

    关闭防火墙和selinux systemctl stop firewalld systemctl disable firewalld sed -ri '/^SELINUX=/cSELINUX=disa ...

  3. Nodejs微信开发使用wechat-api回复多条消息

    在上一往篇文章<Nodejs微信开发>中,微信后台能够正常的接收到客户端的消息,并能够简单的回复一条消息至客户端. 但我的目录是将微信与Bot Framework进行关联,那么肯定就有一些 ...

  4. configure.ac中AC_CHECK_LIB的问题

    编译Linux程序时,使用configure.ac生成的configure程序,时常会出现AC_CHECK_LIB检查某个库失败 而相应库通常是存在的,只是依赖于其他的库,此时,需要乃至AC_CHEC ...

  5. (15)python 数据库连接

    python连接mysql两种方法 一.python官网提供的 MySQL-python 软件 下载地址 https://pypi.python.org/pypi/MySQL-python/1.2.5 ...

  6. HDU 5695 Gym Class && 百度之星 初赛 1006

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5695 本文链接:http://www.cnblogs.com/Ash-ly/p/5515234.htm ...

  7. Codeforces 1039A. Timetable

    题目地址:http://codeforces.com/problemset/problem/1039/A 题目的关键在于理清楚思路,然后代码就比较容易写了 对于每一个位置的bus,即对于每一个i(i& ...

  8. Ubuntu 终端常用命令

    文件目录类 1.建立目录:mkdir 目录名 2.删除空目录:rmdir 目录名 3.无条件删除子目录: rm -rf 目录名 4.改变当前目录:cd 目录名 (进入用户home目录:cd ~;进入上 ...

  9. 理解XML-RPC

    有关XML-RPC http://baike.baidu.com/link?url=ejidFtjelUzPv75VBm5_XrzSbHtFgArYY47S1s1NK2_m-auOr10sTeRh6U ...

  10. 软件配置篇-java下载及安装

    1.进入java官网下载合适版本: 下载地址:https://www.oracle.com/technetwork/java/javase/downloads/index-jsp-138363.htm ...