加入收藏 | 设为首页 | 会员中心 | 我要投稿 安卓应用网 (https://www.0791zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 程序设计 > 正文

对象创建的依赖

发布时间:2020-05-23 08:29:38 所属栏目:程序设计 来源:互联网
导读:对象创建的依赖 关于依赖的哲学,最典型的违反莫过于对象创建的依赖。自面向对象的大旗树立以来,对于对象创建话题的讨论就从未停止。不管是工厂模式还是依赖注入,其核心的思想就只有一个:如何更好地解耦对象创建的依赖关系。所以,在这一部分,我们就以对

对象创建的依赖

关于依赖的哲学,最典型的违反莫过于对象创建的依赖。自面向对象的大旗树立以来,对于对象创建话题的讨论就从未停止。不管是工厂模式还是依赖注入,其核心的思想就只有一个:如何更好地解耦对象创建的依赖关系。所以,在这一部分,我们就以对象创建为主线,来认识对于依赖关系的设计轨迹,分别论述一般的对象创建、工厂方式创建和依赖注入创建三种方式的实现、特点和区别。

1.典型的违反

一般而言,以new关键字进行对象创建,在.NET世界里是天经地义的事情。在本书7.1节“把new说透”中,就比较透彻地分析了new在对象创建时的作用和底层机制。对.NET程序员而言,以new进行对象创建已经是习以为常的事情,大部分情况下这种方式并没有任何问题。例如:

publicabstractclassAnimal

{

publicabstractvoidShow();

}

publicclassDog:Animal

{

publicoverridevoidShow()

{

Console.WriteLine("Thisisdog.");

}

}

publicclassCat:Animal

{

publicoverridevoidShow()

{

Console.WriteLine("Thisiscat.");

}

}

publicclassNormalCreation

{

publicstaticvoidMain2()

{

Animalanimal=newDog();

}

}

对animal对象而言,大部分情况下具体的Dog类是相对稳定的,所以这种依赖很多时候是无害的。这也是我们习以为常的原因之一。

然而,诚如在本文开始对抽象和具体的概念进行分析的结论一样,依赖于具体很多时候并不能有效地保证其稳定性的状态。以本例而言,如果有新的Bird、Horse加入到动物园中来,管理员基于现有体系的管理势必不能适应形式,因为所有创建而来的实例都是依赖于Dog的。所以,普遍的对象创建方式,实际上是对DIP原则的典型违反,高层Animal的创建依赖于低层的Dog,和普世的DIP基本原则是违背的。

因此,DIP并不是时时被OO所遵守,开发者要做的只是适度的把握。为了解决new方式创建对象的依赖违反问题,典型的解决思路是将创建的依赖由具体转移为抽象,通常情况下有两种方式来应对:工厂模式和依赖注入。

2.工厂模式

以工厂模式进行对象创建的方法,主要包括两种模式:抽象工厂模式和工厂方法模式,本文不想就二者的区别和意义展开细节讨论,如果有兴趣可以参阅GoF的《设计模式:可复用面向对象软件的基础》一书。

本文将视角拉回到WCF的IChannelFactory和各种Channel的创建上,以此借用WCF架构中Channel Layer的设计思路,应用工厂模式进行对象创建的设计和扩展,来了解应用工厂模式进行对象创建依赖关系解除的实质和实现。

注意

对于WCF中Channel的概念可以参考相关的资料,在此你只需将其看成一个简单类型即可。

首先来了解一下Channel的创建过程:

publicclassFactoryCreation

{

publicstaticvoidMain()

{

EndpointAddressea=newEndpointAddress("http://api.anytao.com/UserService");

BasicHttpBindingbinding=newBasicHttpBinding();

IChannelFactory<IRequestChannel>facotry=binding.BuildChannelFactory<IRequestChannel>();

facotry.Open();

IRequestChannelchannel=facotry.CreateChannel(ea);

channel.Open();

//Dosomethingcontinue...

}

}

在示例中,IRequestChannel实例通过IChannelFactory工厂来创建,因此关注工厂方式的创建焦点就着眼于IChannelFactory和IRequestChannel上。实质上,在WCF channel Layer中,Channel Factory是创建和管理Channel的工厂封装,通过一个个的Channel Factory来创建一个个对应的Channel实例,所有的Channel Factory必须继承自IChannelFactory,其定义为:

publicinterfaceIChannelFactory<TChannel>:IChannelFactory,ICommunicationObject

{

TChannelCreateChannel(EndpointAddressto);

TChannelCreateChannel(EndpointAddressto,Urivia);

}

通过类型参数TChannel来注册创建实例的类型信息,进而根据EndpointAddress信息来创建相应的对象实例。当然,WCF中的工厂模式应用,还有很多内容值得斟酌和学习。现有篇幅不可能实现完全类似的设计结构,借鉴于WCF的设计思路,对Animal实例的创建进行一点改造,实现基于泛型的工厂模式创建设计,首先定义一个对象创建的模板:

publicinterfaceIAnimalFacotry<TAnimal>

{

TAnimalCreate();

}

然后实现该模板的泛型工厂方法:

publicclassAnimalFacotry<TAnimalBase,TAnimal>:IAnimalFacotry<TAnimalBase>whereTAnimal:TAnimalBase,new()

{

publicTAnimalBaseCreate()

{

returnnewTAnimal();

}

}

其中类型参数TAnimalBase代表了高层类型,而TAnimal则代表了底层类型,其约定关系在where约束中有明确的定义,然后是一个基于对工厂方法的封装:

publicclassFacotryBuilder

{

publicstaticIAnimalFacotry<Animal>Build(stringtype)

{

if(type=="Dog")

{

returnnewAnimalFacotry<Animal,Dog>();

}

elseif(type=="Cat")

{

returnnewAnimalFacotry<Animal,Cat>();

}

returnnull;

}

}

最后,可以欣赏一下基于工厂方式的对象创建实现:

classProgram

{

staticvoidMain(string[]args)

{

IAnimalFacotry<Animal>factory=FacotryBuilder.Build("Cat");

Animaldog=factory.Create();

dog.Show();

}

}

你看,对象创建的依赖关系已经由new式的具体依赖转换为对于抽象和高层的依赖。在本例中,完全可以通过反射方式来消除if/else的运行时类型判定,从而彻底将这种依赖解除为可配置的灵活定制。这正是抽象工厂方式的伟大意义,其实在本例中完全可以将IAnimalFacotry扩展为IAnyFactory形式的灵活工厂,可以在类型参数中注册任何类型的TXXXBase和TXXX,从而实现功能更加强大的对象生成器,只不过需要更多的代码和扩展,读者可以就此进行自己的思考。

(编辑:安卓应用网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读