Aiuto nella scelta della struttura del design: utilizzo di classi o libreria di funzioni

4

Quindi ho una classe GUI che chiamerà un'altra classe chiamata ImageProcessor che contiene una serie di funzioni che eseguiranno algoritmi di elaborazione delle immagini come edgeDetection, gaussianblur, contourfinding, contour map generations, etc. La GUI passa un'immagine a ImageProcessor , che esegue uno di quegli algoritmi su di esso e restituisce l'immagine alla GUI da visualizzare. Quindi essenzialmente ImageProcessor è una libreria di funzioni di elaborazione immagini indipendenti al momento.

Viene chiamato nella GUI come tale

Image image = ImageProcessor.EdgeDetection(oldImage);

Alcune procedure degli algoritmi richiedono molte funzioni e alcune possono essere eseguite in una singola funzione o anche in una sola riga.

Tutte queste funzioni per gli algoritmi integrati in ImageProcessor possono essere piuttosto disordinate e ImageProcessor non sembra che dovrebbe essere una libreria. Quindi stavo pensando di rendere ogni algoritmo una classe con un'interfaccia condivisa diciamo IAlgorithm. Quindi passo l'interfaccia IAlgorithm dalla GUI al ImageProcessor.

public interface IAlgorithm{
   public Image Process();
}
public class ImageProcessor{

  public Image Process(IAlgorithm TheAlgorithm){
        return IAlgorithm.Process();
  }
}

Chiamare la GUI in questo modo

Image image = ImageProcessor.Process(new EdgeDetection(oldImage));

Penso che abbia senso dal punto di vista di un oggetto, ma il problema è che finirò con alcune classi che sono solo una funzione. Cosa ne pensi è un design migliore, o sono entrambi schifo e hai un'idea molto migliore? Grazie!

    
posta roverred 01.11.2013 - 04:45
fonte

3 risposte

5

Ciò di cui hai a che fare qui non sono oggetti, sono funzioni. Prendono argomenti e restituiscono qualcosa di tipo Immagine, non nascondono dati o incapsulano nulla. Alcune persone OO ti diranno che "tutto è un oggetto", ma hanno torto.

Gli argomenti non saranno sempre uguali; potresti avere una funzione di sfocatura che prende un'immagine e un float che indica la quantità di sfocatura da applicare o una funzione di dissolvenza che richiede due immagini e un float che indica la quantità di immagine2 da fondere in immagine1. Non penso che l'idea di un'interfaccia funzioni se le funzioni non prendono gli stessi argomenti.

Trattarli come funzioni è anche più leggibile rispetto agli altri due approcci:

Image image = ImageProcessor.Process(new EdgeDetection(oldImage));

Image image = ImageProcessor.EdgeDetection(oldImage);

Image image = edgeDetect(oldImage);

Se stai usando Java, potrebbe non permetterti di avere funzioni indipendenti, ma puoi usare il tuo approccio originale con istruzioni di importazione statiche per evitare di dover prefissare tutto con ImageProcessor. tutto il tempo.

La tua ImageProcessor non è realmente una classe (non puoi usarla per creare oggetti), è un comodo contenitore per alcune funzioni correlate. Sei tentato di dividerlo in pezzi perché lo stai pensando come una singola grande cosa, ma è già diviso in due parti: è solo che i pezzi sono funzioni, non oggetti o classi.

    
risposta data 01.11.2013 - 07:55
fonte
1

IMO il primo scenerio è più leggibile e facile da capire

Image image = ImageProcessor.EdgeDetection(oldImage);

una semplice chiamata al metodo di utilità

mentre il secondo introduce complessità che non sembrano servire a nessuno scopo

    
risposta data 01.11.2013 - 06:08
fonte
1

Non so se la mia soluzione potrebbe aiutarti, ma penso che creerò un'astrazione:

interface ImageEffect {

    Image apply(Image source);

}

e poi:

class EdgeDetection implements ImageEffect {
    ...
}

class GaussianBlur implements ImageEffect {
    ...
}

Ma, se hai solo 2 o 3 effetti, penso che potresti semplicemente creare un oggetto:

class Picture {

    private Image image;

    public Picture(Image image) {
        this.image = image;
    }

    public Picture edgeDetection() {
        this.image = [...]
    }

    public Picture gaussianBlur() {
        this.image = [...]
    }

    public Image toImage() {
        return image;
    }

}

in modo che alla fine puoi chiamare qualcosa di simile:

[...]
new Picture(myimage)
    .edgeDetection()
    .gaussianBlur()
    .toImage();
[...]

Perché suggerisco 2 modi per risolvere lo stesso problema? Il motivo è che la soluzione di cui hai bisogno dipende da quali "forze" sono coinvolte nel tuo software. Sei l'unico in grado di gestire queste "forze" e il design che creerai sarà semplicemente un "effetto collaterale". Ti suggerisco di usare TDD per trovare il design adatto a te.

    
risposta data 02.04.2014 - 23:15
fonte

Leggi altre domande sui tag