通常情况下,实施Mediator / Director需要 Director 和 同事互相引用。 当Director负责模块 - 生命周期管理(MLM) 时,并不困难:
导演在施工期间自我创建时创建同事:
var Director = function Director($$) {
...
function init(...) {
_moduleA = new ModuleA(this);
_moduleB = new ModuleX(this);
_moduleX = new ModuleX(this);
}
function moduleChanged(ref) {
if (ref === _moduleXYZ) _moduleC.run(ref.datum);
}
return this;
};
AngularJS自动承担了MLM 的负担,因此很难使用上述方法。我们可以稍微修改我们的Director.init方法:
_moduleX = $dependency;
...
_moduleX.init(this);
但[我的]同事需要在施工时提及导演 。
虽然我的导演 实施为EDM(事件驱动的调解)以避免需要DIP,但我现在需要同事来引用导演:
var Colleague = function Colleague(director) {
var thus = this;
...
director.publish(director.CHANNELS.SOME_CHANNEL_NAME, data);
...
return this;
};
这是因为Director 必须现在提供模块授权(MA):
var Director = function Director($$) {
...
function subscribe(channel, handler) {
var args = Array.prototype.slice.call(arguments, 0);
$rootScope.$on.apply($rootScope, args);
return this;
}
function publish(channel) {
var args = Array.prototype.slice.call(arguments, 0);
if (channel in this.CHANNELS) $rootScope.$broadcast.apply($rootScope, args);
return this;
}
return this;
};
那就是说,就DIP / DI而言,实际上没有差异 - 这种方法与更多 Classical 之间的对象参考驱动方法首先提到。
所以我的问题是,有什么不同的方式可以优雅地在Angular中强加DIP和MLM而不会遇到框架问题?
_colleague.init(this);
:BAD _colleague = Colleague.call($dependency, this)
:健康的单身人士??? 将Director Interface应用于每个同事
将 Mediator 类导入(DI)到每个同事:
var Mediator = function Mediator($rootScope) {
...
function subscribe(channel, handler) {
var args = Array.prototype.slice.call(arguments, 0);
$rootScope.$on.apply($rootScope, args);
return this;
}
function publish(channel) {
var args = Array.prototype.slice.call(arguments, 0);
if (channel in this.CHANNELS.SOME_CHANNEL_NAME) $rootScope.$broadcast.apply($rootScope, args);
return this;
}
return this;
};
angular.factory('Mediator', () => Mediator);
var Colleague = function Colleague(Mediator) {
var thus = this;
...
this.publish(this.CHANNELS.SOME_CHANNEL_NAME, data);
// export precepts
Mediator.apply(this);
this.init = init;
...
return this;
};
但是这个可以剥夺导演根据高级应用程序状态进行调解的机会,因为它不会成为Singleton。 E.G:
if (this.state.patientInfoStepComplete) _module.run(ref.datum);
抽象调解员类
与GoF一样,参与者包括 Mediator 和 ConcreteMediator 。
中保:
ConcreteMediator :
为了更接近DIP,我们可以采取" this.CHANNELS
"并将其封装在 Mediator 中,但 ConcreteMediator 仍然需要对它的引用,而且同事需要引用任何提供两者 {{1 }和.CHANNELS
。
你可能想知道为什么我需要一个"混凝土调解员"当我已经实现了一些"抽象调解员"通过使用.publish(...)
无论如何都可以提供请求路由,因为同事使用它来提取频道名称值。原因是,虽然.CHANNELS
可以将一个请求路由到另一个请求,但它只能这样做 - 一个请求 - 而.CHANNELS
可以提供一对多处理 AND 以其他方式作为中间件(例如:MA)。
.publish(...)
您使用过或想过的任何想法或模式?
在Angular中注册/访问依赖项的任何很酷的非标准技巧?
在Angular中以任何方式配置在运行时注入到Services的另一个依赖项吗?
在Director内部的运行时调用var _actions = {
'SOME_CHANNEL_NAME': (e, a, b, c) => {
$rootScope.emit('a', a);
$rootScope.emit('b', b);
$rootScope.emitemit('c', c);
},
};
function publish() {
...
if (channel in this.CHANNELS) _actions[channel].apply(_actions, args);
...
}
提供商 - 构建流程的中间件?
angular.constant('contreteMediator', this);