Paul:工厂模式、以来注入、容器三者的关系

在A类中使用了B类的实例时,B对象的构造不是在A类某个方法中初始化的,而是在A类外部初始化之后以B类的对象传入进来。这个过程就是依赖注入。

这在我们PHP里感触不明显,觉得修改$config和修改$travel = new drive(60,1000)差别不到,一方面是便于管理,另一方面是PHP的非编译型的特性优势。如果用Java来实现,感触就非常明显了,比如程序已经打包了,只需要修改配置文件,就可以控制类的依赖关系了。起到了解耦的作用。

只要不是由内部生产(比如初始化、构造函数 __construct 中通过工厂方法、自行手动 new 的),而是由外部以参数或其他形式注入的,都属于依赖注入(DI) 

1.原始代码:

class Superman
{
    protected $power;

    public function __construct()
    {
        $this->power = new Fight(9, 100); //类嵌套了类 会造成耦合 而且这里面可能会有多个 子类,就会更容易耦合 比如 跑步类、飞行类 by Paul
    }
}

2.工厂模式: 工厂模式只能选择一种小类进行拼装 不能灵活随意组装多个插件 by Paul

 

class SuperModuleFactory
{
    public function makeModule($moduleName, $options)
    {
        switch ($moduleName) {
            case 'Fight': 
                return new Fight($options[0], $options[1]);
            case 'Force': 
                return new Force($options[0]);
            case 'Shot': 
                return new Shot($options[0], $options[1], $options[2]);
        }
    }
}
//统一建一个工厂类,管理里面的小类,这样只需要换掉工厂类即可减低耦合 by Paul

 

class Superman
{
    protected $power;

    public function __construct(array $modules)
    {
        // 初始化工厂
        $factory = new SuperModuleFactory;

        // 通过工厂提供的方法制造需要的模块
        foreach ($modules as $moduleName => $moduleOptions) {
            $this->power[] = $factory->makeModule($moduleName, $moduleOptions);
        }
    }
}

// 创建超人
$superman = new Superman([
    'Fight' => [9, 100],
    'Shot' => [99, 50, 2]
]);

3.依赖注入:


interface SuperModuleInterface
{
    /**
     * 超能力激活方法
     *
     * 任何一个超能力都得有该方法,并拥有一个参数
     *@param array $target 针对目标,可以是一个或多个,自己或他人
     */
    public function activate(array $target);
}
/**
 * X-超能量
 */
class XPower implements SuperModuleInterface
{
    public function activate(array $target)
    {
        // 这只是个例子。。具体自行脑补
    }
}

/**
 * 终极炸弹 (就这么俗)
 */
class UltraBomb implements SuperModuleInterface
{
    public function activate(array $target)
    {
        // 这只是个例子。。具体自行脑补
    }
}
class Superman
{
    protected $module;

    public function __construct(SuperModuleInterface $module)
    {
        $this->module = $module;
    }
}
$superModule = new XPower;
$superMan = new Superman($superModule); //最重要的点是把实例化的类作为参数传入进 类中,需要什么就传入什么类作为参数,这样小类就不会写入到主类里面了,也可以解决第一点的问题,通过工厂模式和依赖注入,可以完成把多个子类封装成一个工厂类,再把工厂类传递给主类 by Paul

4.ioc容器 - 更先进的工厂: 容器实现了随意组装各种超人,而不是一个固定工厂类了,可以装配有超能力的超人,有炸弹能力的超人,或者既有超能力又有炸弹能力的超人 by Paul

class Container
{
    protected $binds;

    protected $instances;

    // 绑定生产对象脚本
    public function bind($abstract, $concrete)
    {
        if ($concrete instanceof Closure) {
        	// 添加脚本
            $this->binds[$abstract] = $concrete;
        } else {
        	// 添加已经写好的对象
            $this->instances[$abstract] = $concrete;
        }
    }


    // 执行生产对象
    public function make($abstract, $parameters = [])
    {
    	// 直接返回已保存的对应$abstract的对象
        if (isset($this->instances[$abstract])) {
            return $this->instances[$abstract];
        }
        // 执行脚本,生产指定$abstract, $parameters的对象
        array_unshift($parameters, $this);


        return call_user_func_array($this->binds[$abstract], $parameters);
    }
}
// 创建一个容器(后面称作超级工厂)
$container = new Container;
//by Paul 重点:把工厂模式里面的工厂类中构建的各种小类组件,做成了可以随意添加的绑定方式,更加灵活,包括主类也绑定到了容器里
// 向该 超级工厂添加超人的组件(主类 by Paul)
$container->bind('superman', function($container, $moduleName) {
    return new Superman($container->make($moduleName));
});

// 向该 超级工厂添加超能力组件
$container->bind('xpower', function($container) {
    return new XPower();
});

// 向该 超级工厂添加炸弹组件
$container->bind('ultrabomb', function($container) {
    return new UltraBomb();
});

// ****************** 华丽丽的分割线 **********************
// 开始启动生产
$superman_1 = $container->make('superman', ['xpower']); //装配有超能力的超人 by Paul
$superman_2 = $container->make('superman', ['ultrabomb']);//装配有炸弹的超人 by Paul
$superman_3 = $container->make('superman', ['xpower','ultrabomb']);装配有超能力、炸弹能力的超人 by Paul
// ...随意添加
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值