我有一些集成(如Salesforce),我想把它们隐藏在产品无关的包装后面(如CrmService类而不是SalesforceService类)。
我可以创建一个CrmService类,并将SalesforceService类用作CrmService中的实现细节,这似乎很简单,但有一个问题。SalesforceService使用了一些异常和枚举。如果我的CrmService抛出SalesforceExceptions,或者你被要求使用Salesforce枚举,那将是很奇怪的。
有什么想法可以让我干净地完成我想要的吗?
编辑:目前,对于例外情况,我正在使用Salesforce,并抛出我自己的自定义。不过我不确定我该怎么做。我想我可以将Salesforce枚举映射到我自己的与提供商无关的枚举,但我正在寻找一个可能比必须进行这种映射更干净的通用解决方案。如果这是我的唯一选项(映射它们),那么这没关系,只是尝试获得想法。
简单的答案是,你走在了正确的轨道上,阅读了德米特定律。
基本概念是给定对象应假定为尽可能少地了解其他任何东西的结构或性质(包括其子组件),根据"信息隐藏"。
遵循德米特定律的优点是软件往往更易于维护和适应性更强。由于对象较少依赖于其他对象、对象的内部结构容器可以在不重新生成调用方的情况下进行更改。
尽管它也可能导致必须编写许多包装器方法将调用传播到组件;在某些情况下,这可能增加明显的时间和空间开销。
所以你看到你正在遵循一个相当好的练习,我通常自己也会遵循,但这确实需要一些努力。
是的,你必须捕捉并抛出自己的异常,映射枚举、请求和响应,这需要大量的前期工作,但如果你在几年后不得不更换Salesforce,你将被视为英雄。
与所有软件开发一样,如果你认为你可能永远不会改变salesforce,你需要付出更多的努力,而不是获得更多的利益?那么它真的需要吗。。。由您决定。
为了利用良好的OOP实践,我将创建一个小型的接口ICrm
,其中包含所有CRM的共同基本成员。该接口将包括典型的方法,如MakePayment()
、GetPayments()
、CheckOrder()
等。例如,还可以创建所需的枚举,如OrderStatus
或ErrorType
。
然后创建并实现实现接口的特定类,例如class CrmSalesForce : ICrm
。在这里,您可以将此特定CRM(在这种情况下为SalesForce)的特定详细信息转换为您的通用ICrm。枚举可以转换为字符串,如果必须的话,可以转换为其他方式(http://msdn.microsoft.com/en-us/library/kxydatf9(v=vs.110).aspx).
然后,作为最后一步,创建CrmService
类并在其中使用依赖注入(http://msdn.microsoft.com/en-us/library/ff921152.aspx),就是这样,在其构造函数中传递一个类型的ICrm
作为参数(如果您愿意,也可以传递方法)。通过这种方式,您可以保持CrmService类的内聚性和独立性,因此您可以创建和使用不同的Crm,而无需更改大部分代码。