Qual è il modo efficace per eliminare la duplicazione? Modelli di progettazione?

1

Ho una classe helper che ha un metodo che esegue alcuni controlli su un campo in un modello. Ho due modelli, ModelA e ModelB , hanno alcune somiglianze ma non tutte. Uno di questi è che entrambi hanno un campo, diciamo stringa ProductCheckField . ProductCheckMethod restituisce il Modello , a causa di ciò ha creato la duplicazione di metodi che fa la stessa cosa ma restituisce un modello diverso. Anche i metodi estratti sono duplicati. Esiste un buon modello di progettazione o qualsiasi altra buona pratica / tecnica che posso usare per eliminare la duplicazione di dover creare due metodi?

N.B Non riesco a utilizzare un'interfaccia condivisa poiché i modelli non sono uguali.

Attualmente ho ..

public class ModelA
   string blah..
   int blah
   .....
   string ProductCheckField


public class ModelB
   string xyz
   int xyz
   .....
   string ProductCheckField

public class HelperClass
{

    public ModelA ProductCheckMethod(ModelA model)
    {
       /// do somthing
       performX(model);
       checkY(model);
       return model;
    }

    public ModelB ProductCheckMethod(ModelB model)
    {
       /// do somthing
       performXDuplicate(model);
       checkYDuplicate(model);
       return model;
    }
}
    
posta user4453701 14.01.2015 - 18:37
fonte

4 risposte

0

Ciò che hai mostrato dei Modelli mostra la stessa interfaccia. Quindi le tue proteste di differenze non sono supportate dall'esempio che tu dai. Ti suggerisco di racchiudere i campi che controlli in performX e checkY con i metodi accessor che vengono comunemente chiamati tra i modelli A e B ed estrai un'interfaccia comune per l'uso della tua classe Helper.

public interface CheckModel
{
    public String getStringValue();
    public void setStringValue(String blahs);
    public int getIntValue();
    public void setIntValue(int blah);
    public String getProductCheckField();
    public void setProductCheckField(String productCheckField);
}

public class ModelA implements CheckModel
{
    String blahs;
   int blah;

   String ProductCheckField;

   public String getStringValue()
    {
        return blahs;
    }

    public void setStringValue(String blahs)
    {
        this.blahs = blahs;
    }

    public int getIntValue()
    {
        return blah;
    }

    public void setIntValue(int blah)
    {
        this.blah = blah;
    }

    public String getProductCheckField()
    {
        return ProductCheckField;
    }

    public void setProductCheckField(String productCheckField)
    {
        ProductCheckField = productCheckField;
    }

}

public class ModelB implements CheckModel
{
    String xyzs;
   int xyz;

   String ProductCheckField;

public String getStringValue()
{
    return xyzs;
}

public void setStringValue(String xyzs)
{
    this.xyzs = xyzs;
}

public int getIntValue()
{
    return xyz;
}

public void setIntValue(int xyz)
{
    this.xyz = xyz;
}

public String getProductCheckField()
{
    return ProductCheckField;
}

public void setProductCheckField(String productCheckField)
{
    ProductCheckField = productCheckField;
}
}

public class HelperClass
{

    public CheckModel ProductCheckMethod(CheckModel model)
    {
       /// do somthing
       performX(model);
       checkY(model);
       return model;
    }

    private void checkY(CheckModel model)
    {
        // ...
    }

    private void performX(CheckModel model)
    {
        // ...
    }

}
    
risposta data 22.01.2015 - 02:55
fonte
2

Sembra che tu abbia una specie di blocco mentale in corso. Se vuoi un design che elimina la duplicazione, dovrai cambiare il tuo in qualche modo , che sembri resistente a fare. Devi guardare oltre il tuo design attuale.

Alcuni modi per eliminare la duplicazione, alcuni dei quali sono migliori di altri:

  • Metti la roba comune dei modelli in una classe comune, con i tuoi modelli contenenti un riferimento a quell'oggetto, come suggerito da Telastyn nei commenti.
  • Reverse del suggerimento di Telastyn, in cui hai una classe ProductCheckStuff , con i puntatori all'interno di it in uno dei modelli.
  • Utilizza i generici in HelperClass o i suoi metodi, con il modello come parametro generico.
  • Chiedi a ogni modello di implementare un'interfaccia con getter per i campi di cui hai bisogno.
  • Estendi il modello da una classe base che implementa ProductCheckMethod .
  • Metti i campi e i metodi di controllo del prodotto in un mixin (se supportato dalla tua lingua) che è mescolato con gli altri campi del tuo modello.

Non puoi fare una frittata senza rompere alcune uova. Hai un sacco di scelte qui. Continua a provarli finché non trovi quello che funziona.

    
risposta data 14.01.2015 - 19:32
fonte
0

È difficile comprendere appieno ciò che è necessario fare qui. Sembra che tu abbia un caso per il pattern Visitor ma hai detto che non puoi usare la stessa interfaccia.

L'unica altra alternativa sarebbe il modello di strategia in cui il CheckMethod sarebbe implementato in una classe di strategia per ciascun modello e invece dei metodi sovraccaricati è possibile utilizzare i generici per associare il modello alla strategia.

public class HelperClass
{
  public T CheckMethod(T model)
  {
    var strategy GetStrategyFor(typeof(T));
    var result = strategy.Execute(model);
    return result;
  }
}

Potresti utilizzare un contenitore IoC o altri metodi per determinare come un tipo si associa a una determinata strategia. Ma una volta che hai fatto ciò, puoi aggiungere nuovi modelli e strategie di abbinamento ai contenuti del tuo cuore.

    
risposta data 14.01.2015 - 19:35
fonte
0

Con i costrutti che hai (incapace di usare un'interfaccia comune) per ModelA e per ModelB, non ci sono molte cose che puoi fare dai Modelli. Comunque potresti generalizzare la classe helper.

Un modo per farlo è,

public class RequestDTO
{
   string xyz_blah;
}

public class ResultDTO. 
{
   string ProductCheckField; 
}

public class HelperClass
{
    public static ResultDTO ProductCheckMethod(RequestDTO request)
    {
        //do something
        ResultDTO result = performXUsingRequestData(model);
        checkYUsingRequestData(model,result);
        return result;
    }       
}

Qui i dati che stai attualmente inviando ai metodi performX, checkY sono aggiunti a RequestDTO e qualunque cosa i dati che vuoi aggiornare sul modello sono aggiunti a ResultDTO.

Nel tuo modello potresti chiamare la classe helper in questo modo,

public class ModelA
{
   string blah..
   int blah
   .....
   string ProductCheckField

   public void ProductCheckMethod()
   {
       RequestDTO dto = new RequestDTO { xyz_blah = blah; }
       ResultDTO result = HelperClass.ProductCheckMethod(dto);
       ProductCheckField = result.ProductCheckField;
   }
}

Lo stesso vale per il Modello B

    
risposta data 22.01.2015 - 04:31
fonte