Esiste un modo migliore per gestire l'astrazione dei dati in questo esempio?

1

Sto costruendo un'applicazione che recupera i dati dell'elenco di Sharepoint tramite un servizio Web SPlists.Lists . Per creare un'istanza del servizio web, ho la seguente classe:

   class SharepointServiceCreator
   {

        public SPlists.Lists createService()
        {
            listsService.Url = "http://wss/sites/SPLists/_vti_bin/lists.asmx";
            listsService.Credentials = System.Net.CredentialCache.DefaultCredentials;
            SPlists.Lists listsService=new SPlists.Lists();
        }

   }

Sono preoccupato che questa non sia una buona astrazione OOP, però, perché per creare questo servizio altrove nella mia applicazione, avrei bisogno del seguente codice:

class someClass
{
 public void someMethod()
 {
  SharepointServiceCreator s=new SharepointServiceCreator()
  SPlists.Lists listService=s.createService()
 }
}

Dovendo usare dichiarare l'istanza di listService in someMethod come tipo SPlists.Lists sembra sbagliata, perché significa che someClass deve sapere come viene implementato SharepointServiceCreator . O è ok?

    
posta sigil 21.09.2012 - 18:31
fonte

2 risposte

2

Questo è un esempio di il modello di fabbrica . Per aderire alle convenzioni esistenti, rinominare SharepointServiceCreator in SharepointServiceFactory e magari renderlo statico in modo che non sia necessario creare un'istanza ogni volta che è necessario un riferimento al servizio.

    
risposta data 21.09.2012 - 19:01
fonte
0

Per fare un ulteriore passo avanti, è possibile creare un'interfaccia e quindi passare l'implementazione. Questo tipo di porta al livello successivo di flessibilità, e puoi farlo più tardi quando scopri le funzioni di cui hai effettivamente bisogno. Una factory può essere utilizzata ad un livello più alto per determinare quale implementazione passi "someClass" nell'argomento costruttore, Oppure puoi usare la factory dappertutto (probabilmente non è la mia prima scelta)

Crea l'interfaccia:

Interface ICreateService {
   CreateService();    
}

e prendi alcuni Dipendenza dell'iniezione in corso, che potrebbero essere automatizzati con qualche tipo di "Contenitore" per andare ancora oltre

class someClass
{
     ICreateService SharePointServices;

     //constructor injection
     public someClass(ICreateService SharepointCreateServiceImplemented)
     {
          SharePointServices = SharepointCreateServiceImplemented;
     }
     public void someMethod()
     { 
          SPlists.Lists listService=SharePointServices.createService()
     }

 }

Ora puoi usare questa classe per qualsiasi oggetto che implementa ICreateService.

Si potrebbe sicuramente fare questo con una fabbrica, dipenderà da dove si desidera individuare la propria implementazione:

class someClass
{    

     public void someMethod()
     { 
         SPlists.Lists listService= (ICreateService)GetServiceFactory("SharePointServiceCreateor").createService()
     }

 }

Dove la fabbrica apparirebbe così:

ICreateService GetServiceFactory(string ImplentationStringOrEnum)
{
    switch(ImplentationStringOrEnum)
    {
        case "SharePointServiceCreator":
            return (ICreateService) new SharePointServiceCreateor();
    }
}

L'intero principio è quello di definire le implementazioni al di fuori delle classi che le stanno utilizzando, in questo modo puoi entrare e uscire facilmente:

    
risposta data 21.09.2012 - 20:14
fonte

Leggi altre domande sui tag