对ObjectBuilder有所了解的可能知道,里面使用了Strategy模式,而在GOF中有这样一句:策略又称做政策(Policy),那问题就来了,在ObjectBuilder中,IBuilderPolicy和IBuilderStrategy到底有什么区别呢?系统为什么会同时引入这两个概念呢?
FrankFei at 2007/07/31
对ObjectBuilder有所了解的可能知道,里面使用了Strategy模式,而在GOF中有这样一句:策略又称做政策(Policy),那问题就来了,在ObjectBuilder中,IBuilderPolicy和IBuilderStrategy到底有什么区别呢?系统为什么会同时引入这两个概念呢?
我们先来看一下类Builder:
public class Builder : BuilderBase<BuilderStage>
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public Builder()
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
: this(null)
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public Builder(IBuilderConfigurator<BuilderStage> configurator)
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Strategies.AddNew<TypeMappingStrategy>(BuilderStage.PreCreation);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Strategies.AddNew<SingletonStrategy>(BuilderStage.PreCreation);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Strategies.AddNew<ConstructorReflectionStrategy>(BuilderStage.PreCreation);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Strategies.AddNew<PropertyReflectionStrategy>(BuilderStage.PreCreation);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Strategies.AddNew<MethodReflectionStrategy>(BuilderStage.PreCreation);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Strategies.AddNew<CreationStrategy>(BuilderStage.Creation);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Strategies.AddNew<PropertySetterStrategy>(BuilderStage.Initialization);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Strategies.AddNew<MethodExecutionStrategy>(BuilderStage.Initialization);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Strategies.AddNew<BuilderAwareStrategy>(BuilderStage.PostInitialization);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Policies.SetDefault<ICreationPolicy>(new DefaultCreationPolicy());
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (configurator != null)
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
configurator.ApplyConfiguration(this);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
}
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
从上面的代码我们可以看出,当我们new Builder()时,会自动把所有的IBuilderStrategy加入到StrategyList(Strategies)中,即当我们实例化一个Builder时,所有的策略(Strategy)已经被加入到StrategyList中了,也就是说,对于策略(Strategy)的使用,是由ObjectBuilder本身处理的,不需要程序使用者干预。那ObjectBuilder中共有九个策略(Strategy),程序使用者每一次不一定需要全部使用,可能只使用其中的一个或多个,那该如何控制呢?这时ObjectBuilder就引入了Policy。
在ObjectBuilder的Strategies目录下有很多具体策略(Strategy),仔细查看你会发现,基本上每个具体的Strategy都对应一个Policy,比如TypeMappingStrategy对应TypeMappingPolicy,SingletonStrategy对应SingletonPolicy,PropertySetterStrategy对应PropertySetterPolicy等。
ObjectBuilder在BuildUp一个对象时,会调用DoBuildUp这个方法,如下:
public class BuilderBase<TStageEnum> : IBuilder<TStageEnum>
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
private object DoBuildUp(IReadWriteLocator locator, Type typeToBuild, string idToBuild, object existing,
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
PolicyList[] transientPolicies)
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
IBuilderStrategyChain chain = strategies.MakeStrategyChain();
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
ThrowIfNoStrategiesInChain(chain);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
IBuilderContext context = MakeContext(chain, locator, transientPolicies);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
IBuilderTracePolicy trace = context.Policies.Get<IBuilderTracePolicy>(null, null);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (trace != null)
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
trace.Trace(Properties.Resources.BuildUpStarting, typeToBuild, idToBuild ?? "(null)");
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
object result = chain.Head.BuildUp(context, typeToBuild, existing, idToBuild);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (trace != null)
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
trace.Trace(Properties.Resources.BuildUpFinished, typeToBuild, idToBuild ?? "(null)");
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return result;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
}
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
从上面的代码中我们可以看出,ObjectBuilder在DoBuildUp时,是从责任链上的第一个对象开始创建具体策略(Strategy),在创建具体策略(Strategy)时,具体策略(Strategy)中包含了对Policy的引用,如果对应的Policy不为空,则处理相应的Policy,看如下代码:
public class TypeMappingStrategy : BuilderStrategy
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public override object BuildUp(IBuilderContext context, Type t, object existing, string id)
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
DependencyResolutionLocatorKey result = new DependencyResolutionLocatorKey(t, id);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
ITypeMappingPolicy policy = context.Policies.Get<ITypeMappingPolicy>(t, id);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (policy != null)
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
result = policy.Map(result);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
TraceBuildUp(context, t, id, Properties.Resources.TypeMapped, result.Type, result.ID ?? "(null)");
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Guard.TypeIsAssignableFromType(t, result.Type, t);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return base.BuildUp(context, result.Type, existing, result.ID);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
}
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
所以在第一次BuildUp一个对象时,ObjectBuilder会依次执行完责任链上的所有策略(Strategy),同时查看Strategy有没有对应的Policy,然后做相应的处理。此时我们还可以再加深理解一下责任链模式的应用。
写到这里,我想你应该对ObjectBuilder中的Strategy和Policy有所了解了,以上只是我个人理解,不当之处请指教!