加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

对象创建的依赖

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

对象创建的依赖

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

1.典型的违反

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

public?abstract?class?Animal

{?

????public?abstract?void?Show();

}

?

public?class?Dog?:?Animal

{

????public?override?void?Show()

????{

????????Console.WriteLine("This?is?dog.");

????}

}

?

public?class?Cat?:?Animal

{

????public?override?void?Show()

????{

????????Console.WriteLine("This?is?cat.");

????}

}

?

public?class?NormalCreation

{

????public?static?void?Main2()

????{

????????Animal?animal?=?new?Dog();

????}

}

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

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

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

2.工厂模式

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

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

????????????????????????????? 注意????????????????????????????????????????????????????????????????????

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

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

public?class?FactoryCreation

{

????public?static?void?Main()

????{

????????EndpointAddress?ea?=?new?EndpointAddress("http://api.anytao.com?/UserService");

????????BasicHttpBinding?binding?=?new?BasicHttpBinding();

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

????????facotry.Open();

????????IRequestChannel?channel?=?facotry.CreateChannel(ea);

????????channel.Open();

????????//Do?something?continue...

????}

}

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

public?interface?IChannelFactory<TChannel>?:?IChannelFactory,?ICommunicationObject

{

????TChannel?CreateChannel(EndpointAddress?to);

????TChannel?CreateChannel(EndpointAddress?to,?Uri?via);

}

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

public?interface?IAnimalFacotry<TAnimal>

{

????TAnimal?Create();

}

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

public?class?AnimalFacotry<TAnimalBase,?TAnimal>?:?IAnimalFacotry<TAnimalBase>?where?TAnimal?:?TAnimalBase,?new()

{

????public?TAnimalBase?Create()

????{

????????return?new?TAnimal();

????}

}

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

public?class?FacotryBuilder

{

????public?static?IAnimalFacotry<Animal>?Build(string?type)

????{

????????if?(type?==?"Dog")

????????{

????????????return?new?AnimalFacotry<Animal,?Dog>();

????????}

????????else?if?(type?==?"Cat")

????????{

????????????return?new?AnimalFacotry<Animal,?Cat>();

????????}

?

????????return?null;

????}

}

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

class?Program

{

????static?void?Main(string[]?args)

????{

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

????????Animal?dog?=?factory.Create();

????????dog.Show();

????}

}

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

本文节选自《你必须知道的.NET(第2版)》一书

图书详细信息:http://www.voidcn.com/article/p-mtfsjtot-ot.html

(编辑:李大同)

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

    推荐文章
      热点阅读