Nel nostro sistema ci siamo imbattuti in god object
. Il sistema è costituito da public service
esposto ai nostri clienti, middle office service
e back office service
.Refactoring oggetti di Dio nei servizi WCF
Il flusso è la seguente: utente registra qualche operazione in public service
, poi direttore dal middle office service
controlli la transazione e approva o rifiuta la transazione e infine direttore dal back office service
finalizza o rifiuta la transazione.
I'am usando la parola transaction
, ma in realtà questi sono i diversi tipi di operazioni come CRUD on entity1
, CRUD on entiny2
... non solo CRUD
operazioni, ma molte altre operazioni come approve/send/decline entity1
, make entity1 parent/child of entity2
etc etc ...
Ora I contratti di servizio WCF
vengono semplicemente separati in base a quelle parti del sistema. Quindi abbiamo 3 contratti di servizio:
PublicService.cs
MiddleOfficeService.cs
BackOfficeService.cs
e quantità enorme di contratti di gestione in ogni:
public interface IBackOfficeService
{
[OperationContract]
void AddEntity1(Entity1 item);
[OperationContract]
void DeleteEntity1(Entity1 item);
....
[OperationContract]
void SendEntity2(Entity2 item);
....
}
Il numero di tali contratti di gestione sono già 2000 in tutti i 3 servizi e circa 600 per ogni contratto di servizio . Non è solo rompere le migliori pratiche, è un enorme problema aggiornare semplicemente i riferimenti di servizio in quanto richiede anni. E il sistema cresce ogni giorno e sempre più operazioni vengono aggiunte a tali servizi in ogni iterazione.
E ora stiamo affrontando il dilemma come possiamo dividere quei servizi divini in parti logiche. Si dice che un servizio non dovrebbe contenere più di 12 ~ 20 operazioni. Altri dicono cose diverse. Mi rendo conto che non esiste una regola d'oro, ma vorrei solo sentire alcune raccomandazioni al riguardo.
Ad esempio, se suddivido questi servizi per tipo di entità, è possibile ottenere circa 50 endpoint di servizio e 50 riferimenti di servizio nei progetti. Che cos'è la manutenibilità in questo caso?
Un'altra cosa da considerare. Supponiamo che io scelga l'approccio per dividere quei servizi per entità. Per esempio:
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);
}
Ora quello che succede è che dovrei aggiungere riferimento a questo servizio sia in public client
e back office client
. Ma back office
richiede solo operazioni FinalizeEntity1
e DeclineEntity1
. Quindi, ecco una violazione classica di Interface segregation principle
in SOLID
. Quindi devo dividere ulteriormente i tre servizi distinti come IEntity1FrontService
, IEntity1MiddleService
, IEntity1BackService
.
Quanto tempo ci vuole per rigenerare il proxy client? – ken2k
@ ken2k, l'intero processo può durare 15 minuti. Per i primi 1-2-3 tentativi è solo timeout e quindi aggiornamenti. Ci vogliono 3-4 minuti per ottenere il timeout. A volte timeout 2 volte, a volte solo una volta. A volte 3 volte Ma questa non è la cosa principale. La priorità è il refactoring. Anche se ci vorrebbero 1 secondo per aggiornare il riferimento, decideremo il refactoring nonostante ciò. –
Potrei fornire una soluzione con ancora solo 3 servizi, ma le 3 interfacce/implementazioni separate in più interfacce/implementazioni usando l'ereditarietà dell'interfaccia e le implementazioni parziali. Questo però non risolverebbe il tempo di rigenerazione del proxy client. – ken2k