ilvsx

第 501 位会员

会员
个人信息
个人成就
  • 发表文章次数 0
  • 发布回复次数 24
  • 个人主页浏览次数 10
对接口和事件概念的深究 -设计模式的依赖颠倒3年前

@fecommerce [[#5楼](#comment5)](#comment5) 我只是不赞成 间接实现B依赖A 这个说法哈,因为 B 只依赖于接口,实例化 B 的时候和 A 没有任何关系。


class A
{
    public function foo(){
        $b = new B();
        $b->bar();
    }
}

class B
{
    public function bar(){
        
    }
}

这是 A 依赖于 B 的情况。


interface IB
{
    public function bar();
}

class B implements IB
{
    public function bar() {}
}

class A
{
    private $b;

    public function __construct(IB $b)
    {
        $this->b = $b;
    }

    public function foo(){
        $this->b->bar();
    }
}

定义一个接口 IB,然后通过构造方法把依赖注入进去。
就变成了的 A 依赖于接口 IB,在实例化 A 的时候,需要传入接口 IB 的实现,这里可以说 A 间接依赖于 B

$a = new A(new B());

但是 B 只依赖于接口 IB,是接口的一个实现,和 A 没有关系,并没有 间接实现B依赖A

$b = new B();
Yii2 自带事件的用法3年前

我翻了下文档…… 发现楼主这个确实是 Yii 的事件的正确使用姿势…… 好尴尬啊…… 没看文档没看源码就直接回答了…… 只是看起来有点像装饰器模式…… 怎么办…… 好尴尬……

http://www.yiiframework.com/doc-2.0/yii-db-baseactiverecord.html#beforeSave()-detail
这里的 beforeSaveafterSave 其实就是触发的 EVENT_BEFORE_INSERTEVENT_AFTER_INSERT 事件。


@xjdata [[#11楼](#comment11)](#comment11) yii2 的 ActiveRecord 已经提前预制好了 ⑨ 个事件,如下:

http://www.yiiframework.com/doc-2.0/yii-db-baseactiverecord.html#EVENT_AFTER_DELETE-detail

你只需要添加对应的处理就可以了:
http://www.getyii.com/doc-2.0/guide/concept-events.html#

看这个文档的 类级别的事件处理器 部分,那个例子应该就是你想要的了……

头像设置的疑惑3年前

把图片地址丢到 session 里,然后验证的时候验证数据有没有在 session 里即可

关于http和https的疑惑3年前

仔细想了下,你的问题其实是跨域问题吧……

看这个,第二段:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS

注意:有些浏览器不允许从HTTPS的域跨域访问HTTP,比如Chrome和Firefox,这些浏览器在请求还未发出的时候就会拦截请求,这是一个特例。)

所以你这个问题,看看对方的 api 支不支持 https 协议,不行的话只能放弃全站 https 了。

还有个可行的方法是在服务端发起对第三方 api 的请求,这样就不会受浏览器的限制了……

对接口和事件概念的深究 -设计模式的依赖颠倒3年前

有点问题…… 反转A和B的依赖关系,让A依赖B反转为B依赖A,那 B 依赖于 A 又怎么解决……

看这个 https://codingstyle.cn/topics/192:

依赖倒置原则则强调:为了让依赖关系是稳定的,不应该由实现侧根据自己的技术实现方式定义接口,然后强迫上层(即客户)依赖这种不稳定的API定义,而是应该站在上层(即客户)的角度去定义API(正所谓依赖倒置)。

但是,虽然接口由上层定义,但最终接口的实现却依然由下层完成,因此依赖倒置描述为:上层不依赖下层,下层也不依赖上层,双方共同依赖于抽象。

依赖倒置原则

还有这里 http://my.oschina.net/zgldh/blog/389243#OSC_h1_1 ,Laravel 框架的作者写的:

最后的原则是依赖反转原则,它规定高等级的代码不应该依赖低等级的代码。首先,高等级的代码应该依赖着抽象层,抽象层就像是“中间人”一样,负责连接着高等级和低等级的代码。其次,抽象定义不应该依赖着具体实现,但具体实现应该依赖着抽象定义。

Yii2 自带事件的用法3年前
<?php

abstract class Model
{

  private $event;

  public function __construct(Event $event)
  {
    $this->event = $event;
  }

  public function save()
  {
    $this->event->notify('saving', $this);
  }

}

class User extends Model
{
}

class Blog extends Model
{
}

class Event
{
  private $events;

  public function addObserver($name, IObserver $observer){
    $this->events[$name][] = $observer;
  }

  public function notify($name, $model){
    echo get_class($model) . PHP_EOL;
    foreach ($this->events[$name] as $observer) {
      $observer->doSomething($model);
    }
  }
}

interface IObserver{
  public function doSomething(Model $model);
}

class LogObserver implements IObserver{
  public function doSomething(Model $model){
    echo 'Log...' . PHP_EOL;
  }
}

class CacheObserver implements IObserver{
  public function doSomething(Model $model){
    echo 'Cache...' . PHP_EOL;
  }
}


$event = new Event();
$event->addObserver('saving', new LogObserver());
$event->addObserver('saving', new CacheObserver());

$user = new User($event);
$user->save();
$blog = new Blog($event);
$blog->save();

执行结果:

User
Log...
Cache...
Blog
Log...
Cache...

@xjdata [#8楼](#comment8) 这是可以满足那段描述的一个实现。 别看那么长…… 其实就是 Model 里的 save() 方法触发 saving 事件,然后 Event 里依次通知(执行)注册(添加)好的观察者LogObserverCacheObserver

Yii2 自带事件的用法3年前

这个应该是装饰器模式,作用是可以动态的添加和修改功能(其实只是看起来比较像装饰器模式,无视无视……)

事件的话,也就是观察者模式,触发一个事件后通知所有观察这个事件的观察者,观察者可以是多个。比如当保存一个 Model 的时候,触发 saving 事件,这个时候就可以编写一个保存日志和一个更新缓存的观察者,以后只要保存 Model ,就可以把日志记录下来,同时更新缓存