在阅读 chromium 网络栈源码时,经常需要去跟踪类中的 delegate_ 成员具体的类别,
后来发现这应该是某种设计模式,因此拿出设计模式书籍看了下经典的 23 种设计模式,
发现有可能相关的是观察者模式和访问者模式,但在仔细了解了这两种模式后,发现 delegate_
的设计并不属于这两种,而跟委托模式比较像:
先来看 delegate_ 的设计方式,下面是 chromium 的源码:
class HttpStreamFactory::Job
: public SpdySessionPool::SpdySessionRequest::Delegate {
public:
......
// Delegate to report Job's status to HttpStreamRequest and HttpStreamFactory.
class NET_EXPORT_PRIVATE Delegate {
public:
virtual ~Delegate() {}
// Invoked when |job| has an HttpStream ready.
virtual void OnStreamReady(Job* job, const SSLConfig& used_ssl_config) = 0;
......
}
Job(Delegate* delegate,
......
);
~Job() override;
private:
// Unowned. |this| job is owned by |delegate_|.
Delegate* const delegate_;
......
} ;
可以看到,在 Job 这个类中,定义了一个类 Delegate,拥有该类的一个指针成员,
Delegate 类定义了一些接口,Job 类构造时传入了 Delegate 类的实例指针,当 Job 类
的实例在执行某些操作时,会通过 delegate_ 调用这些接口,即完成委托的动作。
这里的委托者为 Delegate 的派生类,这里叫做 JobController,被委托者为 Job 类。
class HttpStreamFactory::JobController: public HttpStreamFactory::Job::Delegate {
public:
int HttpStreamFactory::JobController::DoCreateJobs() {
main_job_ = job_factory_->CreateMainJob( this, ......);
}
......
private:
std::unique_ptr<Job> main_job_;
......
};
可以看到,委托类在构造被委托类实例时,将自己的指针传进去,在被委托类中以 delegate_
成员的形式存在。
最后我们看下委托动作的执行,以 OnStreamReady 接口为例,下面是完整的调用代码:
void HttpStreamFactory::Job::OnStreamReadyCallback() {
DCHECK(stream_.get());
DCHECK_NE(job_type_, PRECONNECT);
DCHECK(!is_websocket_ || try_websocket_over_http2_);
MaybeCopyConnectionAttemptsFromSocketOrHandle();
delegate_->OnStreamReady(this, server_ssl_config_);
// |this| may be deleted after this call.
}
在 Job 类的回调方法 OnStreamReadyCallback 中,调用了委托类的方法 OnStreamReady,
可以看到委托者和被委托者的方法不一定同名,浅谈结束。