【发布时间】:2015-09-11 21:53:37
【问题描述】:
我们在系统中遇到了god object。该系统由暴露给我们客户的public service、middle office service 和back office service 组成。
流程如下:用户在public service注册一些交易,然后来自middle office service的经理检查交易并批准或拒绝交易,最后来自back office service的经理完成或拒绝交易。
我使用的是 transaction 这个词,但实际上这些是不同类型的操作,例如 CRUD on entity1、CRUD on entiny2...不仅是 CRUD 操作,还有许多其他操作,例如 approve/send/decline entity1、@987654333 @等等等等……
现在WCF 服务合同只是根据系统的这些部分进行分离。所以我们有 3 个服务合同:
PublicService.cs
MiddleOfficeService.cs
BackOfficeService.cs
每个都有大量的运营合同:
public interface IBackOfficeService
{
[OperationContract]
void AddEntity1(Entity1 item);
[OperationContract]
void DeleteEntity1(Entity1 item);
....
[OperationContract]
void SendEntity2(Entity2 item);
....
}
所有 3 项服务的运营合同数量已经达到 2000 个,每个服务合同大约有 600 个。这不仅破坏了最佳实践,而且更新服务引用是一个巨大的痛苦,因为它需要很长时间。而且系统每天都在增长,并且在每次迭代中向这些服务添加越来越多的操作。
现在我们面临两难境地,即如何将这些上帝服务拆分为逻辑部分。有人说一个服务不应该包含超过 12~20 个操作。其他人说一些不同的话。我意识到没有黄金法则,但我只是希望听到一些关于此的建议。
例如,如果我只是按实体类型拆分这些服务,那么我可以在项目中获得大约 50 个服务端点和 50 个服务引用。在这种情况下,可维护性如何?
还有一点需要考虑。假设我选择将这些服务拆分为每个实体的方法。例如:
public interface IEntity1Service
{
[OperationContract]
void AddEntity1(Entity1 item);
[OperationContract]
void ApproveEntity1(Entity1 item);
[OperationContract]
void SendEntity1(Entity1 item);
[OperationContract]
void DeleteEntity1(Entity1 item);
....
[OperationContract]
void FinalizeEntity1(Entity1 item);
[OperationContract]
void DeclineEntity1(Entity1 item);
}
现在发生的事情是我应该在public client 和back office client 中都添加对此服务的引用。但是back office 只需要FinalizeEntity1 和DeclineEntity1 操作。所以这是SOLID 中对Interface segregation principle 的经典违反。因此,我必须将其进一步拆分为 3 个不同的服务,例如 IEntity1FrontService、IEntity1MiddleService、IEntity1BackService。
【问题讨论】:
-
重新生成客户端代理需要多长时间?
-
@ken2k,整个过程可能会持续 15 分钟。对于前 1-2-3 次尝试,它只是超时然后更新。超时需要 3-4 分钟。有时它会超时 2 次,有时只有一次。有时3次。但这不是主要的。优先级是重构。即使更新参考需要 1 秒钟,我们仍会决定重构。
-
我可以提供一个仍然只有 3 个服务的解决方案,但是使用接口继承和部分实现将 3 个接口/实现分成多个接口/实现。不过,这并不能解决客户端代理的重新生成时间。
-
@ken2k,它已经被分成3个不同的
ServiceContracts和3个不同的implementations。 -
我发布了这个想法作为答案,希望它更清楚
标签: wcf soa servicecontract