[浪子学编程][MS Enterprise Library]ObjectBuilder内功心法之中国特色
ObjectBuilder内功心法之中国特色
-Written by 浪子
摘要:
ObjectBuilder 模块的代码断断续续已经读了半个月左右了,今天突然间豁然开朗,顿悟出其中的奥妙。正所谓:“迷人若悟心开,与大智人无别。故知不悟,即佛是众生;一念若悟,即众生是佛。”。
经过日复一日的刻苦修行,我佛慈悲,终于顿悟心开,成为大智人了。用慧眼旁观EnterLib之ObjectBuilder,发现其中蕴涵如此厚重的中国底蕴气息,以致于我要怀疑微软公司模式与实践小组的成员是不是中国某些政府部门偷渡跳槽过去的:)
þ 第二代身份证(责任链模式&策略模式):
当我还怀揣着两张不旧不新的身份证的时候,却被通知需要重新办理第二代居民身份证,我真是那个晕啊。不过相对那些刚办完旧的身份证,第二个月就被通知再次办理新的第二代身份证的同志嘛,呵呵……
不过通知归通知,由于迫于生计没日没月的加班加点,办证的那帮“大爷”又是从来不要加班的,所以下班后去要求他加班帮我办理身份证,显然是不可能di;虽然办新证是他们要求我的,但是我却只能把他们尊为“大爷”……(My God,这是什么世道啊!)
好不容易手头上的项目暂告一段落,忙里偷闲中决定去把这件烦心事给了了,以免夜长梦多,那些个“大爷”耍大牌出怪招,那俺这些小民可承受不起。
//办证方法
public interface IBuilder<TStageEnum>
{
PolicyList Policies { get; }
StrategyList<TStageEnum> Strategies { get; }
//我要办证
object BuildUp(IReadWriteLocator locator, Type typeToBuild, string idToBuild, object existing, params PolicyList[] transientPolicies);
//泛型方法,办理TTypeToBuild 类型的证件,当然此时我们要的是第二代身份证
TTypeToBuild BuildUp<TTypeToBuild>(IReadWriteLocator locator, string idToBuild, object existing, params PolicyList[] transientPolicies);
TItem TearDown<TItem>(IReadWriteLocator locator, TItem item);
}
本来以为直接去办证就可以了,结果发现没那么简单,要这样这样,那样那样……,看来还没有那么容易啊,还需要好多个手续。(当然只有具有办理身份证只能的部门我才需要去那里办理手续)
//办证职能
public interface IBuilderStrategy
{
//我要办证
object BuildUp(IBuilderContext context, Type typeToBuild, object existing, string idToBuild);
}
//政府规定拥有办证职能的部门(策略的抽象基类)
public abstract class BuilderStrategy : IBuilderStrategy
{
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;
}
}
//实现了策略的抽象基类
public class TypeMappingStrategy : BuilderStrategy
public class SingletonStrategy : BuilderStrategy
public abstract class ReflectionStrategy<TMemberInfo> : BuilderStrategy
……
//当然这些部门里面还可能分好多小部门,比如ReflectionStrategy<TMemberInfo>部门,这丫的比较有权力,好多内部部门都拥有办证职能
public class ConstructorReflectionStrategy : ReflectionStrategy<ConstructorInfo>
public class PropertyReflectionStrategy : ReflectionStrategy<PropertyInfo>
public class MethodReflectionStrategy : ReflectionStrategy<MethodInfo>
这些部门还不少啊,出发前,我特意找过来人列了张清单:
1、 厦门人才中心:凭借身份证,毕业证领取户口页;
2、 去公安局指定的照相馆照相;凭借户口页照相交钱,然后领取身份证领取凭证
3、 去户口所在地的公安局领取新身份证:凭借从照相馆拿到的凭证去领新的身份证
由此可看出,其实只有到了最后公安局那里我们才能真正达到我们的目的:办理新的身份证,中间的那些个部门根本就没有权利办理新证件,只不过做了些他们自己的事情(例如收钱......)
//各个部门都要做些自己的事情,但是也不能乱来,组织上还是有些规定了
//空接口
public interface IBuilderPolicy
{
//当然是老样子了,口头上说说而已,挂羊头卖狗肉也
}
//肉到嘴边总不能不吃吧,办证前我也得捞点油水。不过捞归捞还是应该响应组织的号召的
public interface ITypeMappingPolicy : IBuilderPolicy
{
//地方的政策方针
DependencyResolutionLocatorKey Map(DependencyResolutionLocatorKey incomingTypeIDPair);
}
//咱们头ITypeMappingPolicy已经向组织IBuilderPolicy汇报过了,你们放心捞吧
//各个部门的具体实施方针
public class TypeMappingPolicy : ITypeMappingPolicy
{
private DependencyResolutionLocatorKey pair;
public TypeMappingPolicy(Type type, string id)
{
pair = new DependencyResolutionLocatorKey(type, id);
}
public DependencyResolutionLocatorKey Map(DependencyResolutionLocatorKey incomingTypeIDPair)
{
return pair;
}
}
真是犹如乱麻啊,不过我也管不了,我只能按照规定的方法(IBuilder<TStageEnum>)去办理我自己的身份证,为了这个我还准备了一份计划书:
//浪子的办证计划书
public class BuilderBase<TStageEnum> : IBuilder<TStageEnum>
{
//把了解到政策记下来(各个策略的具体实施方针)
private PolicyList policies = new PolicyList();
//把需要经过的部门也给记下来(具体的策略类)
private StrategyList<TStageEnum> strategies = new StrategyList<TStageEnum>();
//啥都准备了,办证可不能忘哦 :)(调用)
private object DoBuildUp(IReadWriteLocator locator, Type typeToBuild, string idToBuild, object existing,PolicyList[] transientPolicies)
//调用之前先武装自己(初始化责任连模式的上下文关系)
//用了解到的政策方针,所有经过的部门都武装到脑袋里,制定执行方案
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);
}
}
全部武装之后,按照计划书实施办证事宜:
//向领导汇报请假,走出公司大楼,面对艰辛的旅途,狼吼一声:老子,来办证了!
public TTypeToBuild BuildUp<TTypeToBuild>
//不过理智告诉我,不能冲动,应该按照执行方案去做
//首先要去人才中心(获取责任连的第一个节点)
chain.Head.BuildUp(context, typeToBuild, existing, idToBuild);
大热天,好不容易从拥挤的bus上挤下来,带着一身的汗水登上人才中心服务大厅。哇靠,门没开。心想完了,这帮***没上班,瞄了眼门上的工作时间表,下午2:30~5:30,晕死不是吧,俺们1:30就开工了,没人性啊。好不容易熬过半个多钟头,大门才缓缓开启,我立马冲上去对着那位老大妈 ,小声的说:我要办身份证 (没辙,人在屋檐下不得不低头)
//我要办身份证
public override object BuildUp(IBuilderContext context, Type t, object existing, string id)
{
DependencyResolutionLocatorKey esult = 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);
}
我的天,经过一系列的吃人事件,终于把办理身份证所需的手续都办理结束,临了我拖着付空骨架回了公司,立马登上公司头版头条新闻:“奇迹:荆艺某同志亲历系列吃人恐怖事件居然生还……”
þ 我辈芸芸众生(上下文关系):
其实之所谓发生如此惨绝人寰的系列吃人事件,罪魁祸首是吃人者无处不在,但是与被吃者自身主动献身也有极大关系。是被吃者为吃人者提供了有用的信息,甚至是自己甘愿送上门去被吃。
//被吃者最佳攻略手册(上下文关系接口规范)
public interface IBuilderContext
{
//第一个吃的人(责任链的第一个节点)
IBuilderStrategy HeadOfChain { get; }
//是不是被吃过了(定位器,用来寻找此对象是否被创建过)
IReadWriteLocator Locator { get; }
//他们想怎么吃,投其所好(具体策略的执行方针)
PolicyList Policies { get; }
//下一个该轮到谁吃(责任链上的下一个具体策略是who?)
GetNextInChain(IBuilderStrategy currentStrategy);
}
//在我们开始要办证的时候就注定了这系列惨剧必定发生
//为出卖自己做好准备(初始化上下文关系)
IBuilderContext context = MakeContext(chain, locator, transientPolicies);
þ 资源再利用(定位器):
在去人才中心被宰的时候,顺便借出了户口页,然后赶快复印一份存起来,再去办理失业证的时候,我就可以在我的备份库里面找到身份证复印件,而避免再次被****
定位器的细节参考园子里其他朋友的文章:
1、niwalker的专栏之ObjectBuilder技术内幕(一)
2、Terrylee之.NET设计模式(11):组合模式(Composite Pattern)