Non riesco a trovare un design (pattern) per un'applicazione / servizio che colpirà più servizi web (API esterne di terze parti), analizzeremo, combineremo e restituiremo in un'unica risposta.
L'applicazione avrà i seguenti comportamenti / passaggi (in nessun ordine particolare):
- Cerca hotel
- Recupera i dettagli dell'hotel selezionato
- Recupera i dettagli della camera dell'hotel selezionato
- Recupera criteri di cancellazione
- Carica addebiti extra per i clienti
- Blocca la room room del libro
- Ottieni i dettagli della camera prenotata
- Annulla la sala prenotata
Non tutte le API avranno / implementeranno i passaggi precedenti. Ad esempio, poche API potrebbero non avere il 3 ° passaggio o il 4 ° passaggio o entrambi. In breve, i passaggi / la combinazione di passaggi possono cambiare in base al provider dell'API.
Una volta avviata una ricerca per hotel dall'applicazione Web, la richiesta verrà inviata a questa applicazione. Recupera quindi tutti i provider API attivi (interfaccia C # comune) dal database e invia la richiesta a ciascuna API. Voglio esporre un'interfaccia comune durante l'istanziazione delle classi del fornitore. La stessa metodologia verrà seguita per ogni passaggio.
Sto cercando di pensare a un modello di design e di progettare una soluzione che rispetti i principi SOLID. Sulla base del requisito di cui sopra, ho pensato ai seguenti schemi ma finora non ho avuto successo:
- Metodo di produzione: definire un'interfaccia comune con tutto quanto sopra passaggi / comportamenti e utilizzare il metodo di fabbrica per creare l'oggetto (s). Tuttavia, questo porterà alla violazione della sostituzione di Liskov principio poiché alcune API potrebbero non implementare tutto.
- Motivo decoratore: definisce un componente (interfaccia) che conterrà i passaggi comuni. Aggiungi passaggi / comportamento in modo dinamico usando decoratore. Tuttavia, con questo design, l'interfaccia del componente non avrà alcuna conoscenza dei passaggi / comportamenti aggiunti che vanificano il nostro scopo di utilizzare un'interfaccia comune.
C'è qualche altro modello che è l'ideale per il mio problema o dovrei andare avanti con la prima soluzione e vivere con la violazione principale?
Esempio di codice per aiutare a chiarire il problema (nessun modello seguito, inteso a chiarire gli attori coinvolti):
public interface IAPIProvider
{
void SearchHotels();
void GetHotelDetails();
void GetRoomDetails();
void GetCancellationPolicies();
void GetExtraGuestChargeDetails();
void BlockRoom();
void BookRoom();
void GetBookingDetails();
void CancelBooking();
}
public class ConcreteProviderA : IAPIProvider
{
public void BlockRoom()
{
//call api
}
public void BookRoom()
{
//call api
}
public void CancelBooking()
{
//call api
}
public void GetBookingDetails()
{
//call api
}
public void GetCancellationPolicies()
{
//call api
}
public void GetExtraGuestChargeDetails()
{
//call api
}
public void GetHotelDetails()
{
//call api
}
public void GetRoomDetails()
{
//call api
}
public void SearchHotels()
{
//call api
}
}
public class ConcreteProviderB : IAPIProvider
{
public void BlockRoom()
{
throw new NotImplementedException();
}
public void BookRoom()
{
//call api
}
public void CancelBooking()
{
//call api
}
public void GetBookingDetails()
{
//call api
}
public void GetCancellationPolicies()
{
throw new NotImplementedException();
}
public void GetExtraGuestChargeDetails()
{
throw new NotImplementedException();
}
public void GetHotelDetails()
{
//call api
}
public void GetRoomDetails()
{
//call api
}
public void SearchHotels()
{
//call api
}
}
/// <summary>
/// Request from web/mobile will land in this class
/// </summary>
public class Client
{
public void SearchHotel()
{
//get active providers from database & instantiate them
List<IAPIProvider> providers = new List<IAPIProvider>();
foreach(var provider in providers)
{
//search hotels from each API provider
provider.SearchHotels();
}
}
public void GetHotelDetails(int hotelId, int hotelProviderId)
{
IAPIProvider provider = null;
//here, resolve the correct API provider using the input parameters
//fetch hotel details from the resolved API provider
provider.GetHotelDetails();
}
//Other methods
}
Esempio di codice come aspetto .