<?php
interface Animal{ public function attack();
public function talk(); } class People implements Animal
{
public $month;
public $hand;
public function __construct(Mouth $mouth,Hand $hand)
{
$this->month = $mouth;
$this->hand = $hand; } public function attack()
{
$this->hand->scrap();
} public function talk()
{
$this->month->say();
} } class Mouth{
public function say(){
echo "咿咿呀呀";
}
}
class Hand{
public $finger;
public function __construct(Finger $finger)
{
$this->finger = $finger;
} public function scrap(){
echo '仍玩具';
} public function otherFunction(){
$this->finger->eatFinger();
}
} class Finger{
public function eatFinger(){
echo "吃手指";
}
} class Container
{
/**
* 容器绑定,用来装提供的实例或者 提供实例的回调函数
* @var array
*/
public $building = []; /**
* 注册一个绑定到容器
*/
public function bind($abstract, $concrete = null, $shared = false){
if(is_null($concrete)){
$concrete = $abstract;
} if(!$concrete instanceOf Closure){
$concrete = $this->getClosure($abstract, $concrete);
} $this->building[$abstract] = compact("concrete", "shared");
} //注册一个共享的绑定 单例
public function singleton($abstract, $concrete, $shared = true){
$this->bind($abstract, $concrete, $shared);
} /**
* 默认生成实例的回调闭包
*
* @param $abstract
* @param $concrete
* @return Closure
*/
public function getClosure($abstract, $concrete){
return function($c) use($abstract, $concrete){
$method = ($abstract == $concrete)? 'build' : 'make';
return $c->$method($concrete);
};
} /**
* 生成实例
*/
public function make($abstract){
$concrete = $this->getConcrete($abstract); if($this->isBuildable($concrete, $abstract)){
$object = $this->build($concrete);
}else{
$object = $this->make($concrete);
} return $object;
} /**
* 获取绑定的回调函数
*/
public function getConcrete($abstract){ if(! isset($this->building[$abstract])){
return $abstract;
} return $this->building[$abstract]['concrete'];
} /**
* 判断 是否 可以创建服务实体
*/
public function isBuildable($concrete, $abstract){ return $concrete === $abstract || $concrete instanceof Closure;
} /**
* 根据实例具体名称实例具体对象
*/
public function build($concrete){ if($concrete instanceof Closure){
return $concrete($this);
} //创建反射对象
$reflector = new ReflectionClass($concrete);//通过反射获取类名 if( ! $reflector->isInstantiable()){
//抛出异常
throw new \Exception('无法实例化');
} $constructor = $reflector->getConstructor();//获取构造函数
if(is_null($constructor)){
return new $concrete;
} $dependencies = $constructor->getParameters();//获取构造函数参数
$instance = $this->getDependencies($dependencies);
return $reflector->newInstanceArgs($instance);//将参数注入到对象中 } //通过反射解决参数依赖
public function getDependencies(array $dependencies){
$results = [];
foreach( $dependencies as $dependency ){
$results[] = is_null($dependency->getClass())
?$this->resolvedNonClass($dependency)
:$this->resolvedClass($dependency);
} return $results;
} //解决一个没有类型提示依赖
public function resolvedNonClass(ReflectionParameter $parameter)
{
if($parameter->isDefaultValueAvailable()){
return $parameter->getDefaultValue();
}
throw new \Exception('出错'); } //通过容器解决依赖
public function resolvedClass(ReflectionParameter $parameter)
{
return $this->make($parameter->getClass()->name); } }
//实例化容器类
$container = new Container();
$container->bind('Animal','People');//将需要创建对象的类放到容器中
$people = $container->make('Animal');//创建对象
$people->attack();//调用方法
$people->talk();

最新文章

  1. visio2007使用记录
  2. Redis介绍及常用命令
  3. [windows操作系统]内核性能剖析
  4. java apache commons HttpClient发送get和post请求的学习整理(转)
  5. php获得当前日期时间 date函数
  6. js实现选项卡切换的三种方式
  7. 日本IT工作有感
  8. html5获取图片的宽高
  9. merge_partition
  10. 简述Servlet的基本概念
  11. thinkpaidE480office安装文件夹
  12. Scala学习笔记(五):内建控制循环
  13. 阿里云rds实例恢复到本地
  14. 微软必应词典UWP -2017春
  15. HTTPS-HTTPS原理
  16. JAVA unicode转换成中文
  17. html 列表相关信息
  18. 在虚拟机中安装ubuntu16.04后不能全屏显示
  19. centos7之saltstack使用手册
  20. HTML5--Table

热门文章

  1. 通过元类创建一个Python类
  2. django 请求 与 响应
  3. hashlib 加密 与进度条
  4. MySQL多表查询答案
  5. 深度探索MySQL主从复制原理
  6. git clone一个仓库下的单个文件【记录】
  7. Logback+ELK+SpringMVC搭建日志收集服务器
  8. 关于Eclipse导入maven项目报空指针异常
  9. UML软件工程第一次实验
  10. 点击其它位置,div下拉菜单消失