ObjectBuilder之设计模式(二):责任链模式
- Written by 浪子 [walkingboy.cnblogs.com]
摘要:
古语云:蛇无头不行,鸟无头不飞。
协同工作对于团队的重要意义勿庸置疑。好的团队,有好的责任制度,每个人各司其职。
组织策略:策略管道(Pipeline Stages)
在ObjectBuilder之设计模式(一):策略模式 一文中,罗列出了许多创建策略,每个策略分属于不同的创建阶段;
人多并不见得力量大,有组织有纪律的团队才能发挥最大的潜力。当创建策略到处存在的时候,如果不进行适当地组织,则犹如一盘散沙。在ObjectBuilder里面用策略管道(Pipeline Stages)来分配具体策略的各自作用范围:
//
作用范围即创建阶段
public
enum
BuilderStage

{
PreCreation,

Creation,

Initialization,

PostInitialization
}
预创建阶段(PreCreation):
TypeMappingStrategy : 类型映射策略
SingletonStrategy: 单例策略
ConstructorReflectionStrategy: 构造器反射策略
PropertyReflectionStrategy: 属性反射策略
MothodReflectionStrategy: 方法反射策略
创建阶段(Creation):
CreationStrategy: 创建策略
初始化阶段(Initialization):
PropertySetterStrategy: 属性设置器策略
MothodExecutionStrategy: 方法执行策略
初始化完成阶段(PostInitialization):
BuilderAwareStrategy: 创建器感知策略
//
按不同阶段组织创建策略
public
StrategyList()

{
stages
=
new
Dictionary
<
TStageEnum, List
<
IBuilderStrategy
>>
();
foreach
(TStageEnum stage
in
stageValues)
stages[stage]
=
new
List
<
IBuilderStrategy
>
();

}
创建责任链:
“责任链模式是一种对象的行为模式【GOF95】。在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织链和分配责任。”
可见,责任链模式,关键的就是如何组织链和分配责任。而ObjectBuilder的组织纽带很明显的就是创建行为(BuildUp),而责任则分散在各个具体的创建策略内,通过具体的策略方针来决定是否执行相关创建责任(创建责任见上文:ObjectBuilder之设计模式(一):策略模式 )
对象创建顺序:

依赖注入部分(Reflection):

组织链结构体系已经明朗,接下来需要解决的问题是如何传递责任。显然策略管道(Pipeline Stages)只是设定了创建策略的作用范围,但是并不能解决相同范围内的策略如何传递责任,也无法处理不同作用范围之间的责任的衔接,所以我们必须维护一个传递规则,也就责任链摸式的关键元素:“上下文关系”
策略责任链:

上下文关系:

设置参与创建过程的创建策略:
//
类型映射策略
Strategies.AddNew
<
TypeMappingStrategy
>
(BuilderStage.PreCreation);

//
单例策略
Strategies.AddNew
<
SingletonStrategy
>
(BuilderStage.PreCreation);

//
构造器反射策略
Strategies.AddNew
<
ConstructorReflectionStrategy
>
(BuilderStage.PreCreation);

//
属性反射策略
Strategies.AddNew
<
PropertyReflectionStrategy
>
(BuilderStage.PreCreation);

//
方法反射策略
Strategies.AddNew
<
MethodReflectionStrategy
>
(BuilderStage.PreCreation);

//
创建策略
Strategies.AddNew
<
CreationStrategy
>
(BuilderStage.Creation);

//
属性设置器策略
Strategies.AddNew
<
PropertySetterStrategy
>
(BuilderStage.Initialization);

//
方法执行策略
Strategies.AddNew
<
MethodExecutionStrategy
>
(BuilderStage.Initialization);

//
创建器感知策略
Strategies.AddNew
<
BuilderAwareStrategy
>
(BuilderStage.PostInitialization);

初始化策略责任链:
//
正向装载策略责任链
IBuilderStrategyChain chain
=
strategies.MakeStrategyChain();

//
装载方法
public
IBuilderStrategyChain MakeStrategyChain()

{
lock
(lockObject)

{
BuilderStrategyChain result
=
new
BuilderStrategyChain();
foreach
(TStageEnum stage
in
stageValues)
result.AddRange(stages[stage]);
return
result;
}

}

责任链的内容已经配置完毕,现在需要初始化上下文关系,以便于在各个策略间传递相关消息:
//
初始化责任链上下文
IBuilderContext context
=
MakeContext(chain, locator, transientPolicies);
//
初始化上下文方法

/**/
///
<summary>
///
初始化责任链的上下文环境
///
</summary>
private
IBuilderContext MakeContext(IBuilderStrategyChain chain,IReadWriteLocator locator,
params
PolicyList[] transientPolicies)

{
PolicyList policies
=
new
PolicyList(
this
.policies);
foreach
(PolicyList policyList
in
transientPolicies)
policies.AddPolicies(policyList);
return
new
BuilderContext(chain, locator, policies);

}

首先将责任推给第一个节点:
object
result
=
chain.Head.BuildUp(context, typeToBuild, existing, idToBuild);

通过上下关系确认下一个节点,并将责任推给它
public
virtual
object
BuildUp(IBuilderContext context, Type typeToBuild,
object
existing,
string
idToBuild)

{
IBuilderStrategy next
=
context.GetNextInChain(
this
);
if
(next
!=
null
)
return
next.BuildUp(context, typeToBuild, existing, idToBuild);
else
return
existing;
}


此基类函数是虚函数,如果具体创建策略有自己的具体行为,会override此方法,执行完之后才会将责任推给下一个节点,如TypeMappingStrategy:
//
override基类方法
public
override
object
BuildUp(IBuilderContext context, Type t,
object
existing,
string
id)

{

//
执行自己的具体创建策略
DependencyResolutionLocatorKey result
=
new
DependencyResolutionLocatorKey(t, id);
ITypeMappingPolicy policy
=
context.Policies.Get
<
ITypeMappingPolicy
>
(t, id);
if
(policy
!=
null
)

{
result
=
policy.Map(result);

TraceBuildUp(context, t, id, Properties.Resources.TypeMapped, result.Type, result.ID
??
"
(null)
"
);

Guard.TypeIsAssignableFromType(t, result.Type, t);

}

//
将责任推给下一个节点
return
base
.BuildUp(context, result.Type, existing, result.ID);

}

小结:
写到这里,才想通ObjectBuilder之设计模式(一):策略模式 中的一个问题:
“ObjectBuilder的创建策略(BuilderStrategy),但是他们却不是用来互换的,而是互相补充互相完善了,所以应该是一系列的连贯动作,看起来好像并不完全符合策略模式的定义。”
再看了一下设计模式(17)-Chain of Responsibility Pattern

觉得BuilderStragegy其实并没有构成策略模式,虽然它命名为BuilderStragegy。
因为策略模式的目的是为了互相替换,而BuilderStragegy中的一系列具体策略是为了协同合作一起达到创建对象的目标,所以更符合上面的责任链模式,是责任链中不同阶段的不同Handler。
个人觉得ObjectBuilder的创建过程的理解重点在于责任的传递(即责任链模式的上下文传递),利用多态来分配不同阶段不同创建策略需要执行的具体方针,然后再将责任推给下一个节点。
通过ObjectBuilder创建一个对象如此之复杂,对象的复用事在必行。下次继续资源循环利用之定位器Locator
To Be Continued……
―――――――――――――――――――――――――――――――――――――――――――――
参考资料:
吕震宇老师之设计模式(17)-Chain of Responsibility Pattern
niwalker的专栏之ObjectBuilder技术内幕