We came across a god object
in our system. The system consists of public service
exposed to our clients, middle office service
and back office service
.
The flow is the following: user registers some transaction in public service
, then manager from middle office service
checks the transaction and approves or declines the transaction and finally manager from back office service
finalizes or declines the transaction.
I'am using the word transaction
, but in reality those are different types of operations like CRUD on entity1
, CRUD on entiny2
... Not only CRUD
operations but many other operations like approve/send/decline entity1
, make entity1 parent/child of entity2
etc etc...
Now WCF
service contracts are just separated according to those parts of the system. So we have 3 service contracts:
PublicService.cs
MiddleOfficeService.cs
BackOfficeService.cs
and huge amount of operation contracts in each:
public interface IBackOfficeService
{
[OperationContract]
void AddEntity1(Entity1 item);
[OperationContract]
void DeleteEntity1(Entity1 item);
....
[OperationContract]
void SendEntity2(Entity2 item);
....
}
The number of those operation contracts are already 2000 across all 3 services and approximately 600 per each service contract. It is not just breaking the best practices, it is a huge pain to just update service references as it takes ages. And the system is growing each day and more and more operations are added to those services in each iteration.
And now we are facing dilemma as how can we split those god services into logical parts. One says that a service should not contain more then 12~20 operations. Others say some different things. I realize that there is no golden rule, but I just would wish to hear some recommendations about this.
For example if I just split those services per entity type then I can get about 50 service endpoints and 50 service reference in projects. What is about maintainability in this case?
One more thing to consider. Suppose I choose the approach to split those services per entity. For example:
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);
}
Now what happens is that I should add reference to this service both in public client
and back office client
. But back office
needs only FinalizeEntity1
and DeclineEntity1
operations. So here is a classic violation of Interface segregation principle
in SOLID
. So I have to split that further may be to 3 distinct services like IEntity1FrontService
, IEntity1MiddleService
, IEntity1BackService
.
ServiceContracts
and 3 differentimplementations
. – Loosen