2012-12-14 4 views
41

Sto provando a implementare un modello Factory in Java. Ho una classe chiamata Forma che estende il Cerchio e il Triangolo. Il problema è che il costruttore Shape ottiene solo 2 parametri mentre Circle ha 3 parametri e quindi Triangolo (che non mostrerò nella sezione codice perché è identico a Circle). Per dimostrare meglio:Fabbrica in Java quando gli oggetti concreti prendono diversi parametri del costruttore

private interface ShapeFactory{ 
     public Shape create(int x, int y); 
    } 

    private class CircleFactory implements ShapeFactory{ 
     public Shape create(float radius, int x, int y){ //error 
      return new Circle(radius, x,y); 
     } 
    } 

Delle idee come superare questo problema? Non devo ricevere un input dall'utente all'interno della fabbrica (deve essere ricevuto dall'esterno).

Grazie!

+0

Perché si desidera utilizzare una fabbrica? Cosa stai cercando di ottenere? – miniBill

+1

Pensato che non sia una soluzione dolce, puoi passare una mappa aggiuntiva dei parametri specifici di Shape concreti. Inoltre: è necessario fornire il raggio sulla creazione? È possibile impostare un raggio di default alla creazione e quindi impostare il raggio richiesto dopo aver creato la forma. – nidu

+0

Bene, ho pensato a questa opzione, ma contraddice l'idea del costruttore ... – Jjang

risposta

27

si hanno due opzioni:

1) Abstract Factory:

RectangularShape extends Shape

RoundShape extends Shape

e RectangularShapeFactory e RoundShapeFactory

2) Builder (vedi anche punto 2 in Effective Java)

public Shape { 
    private final int x; 
    private final int y; 
    private final double radius; 

    private Shape(Builder builder) { 
     x = builder.x; 
     y = builder.y; 
     radius = builder.radius; 
    } 

    public static class Builder { 
     private final int x; 
     private final int y; 
     private double radius; 

     public Builder(int x, int y) { 
      this.x = x; 
      this.y = y; 
     } 

     public Builder radius(double radius) { 
      this.radius = radius; 
      return this; 
     } 

     public Shape build() { 
      return new Shape(this); 
     }  
    } 
} 

//in client code 

    Shape rectangle = new Shape.Builder(x,y).build(); 
    Shape circle = new Shape.Builder(x,y).radius(radiusValue).build(); 
+4

Abstract Factory non risolverebbe questo problema. Tutte le implementazioni di 'ShapeFactory' richiedono ancora un'interfaccia comune. – jaco0646

+0

(2) Il builder qui appare come l'anti-pattern localizzatore di servizi implicito. – SerG

6

Quello che stai cercando di fare è semplicemente impossibile. Se gli argomenti del costruttore sono diversi, il codice client dovrà fare un lavoro diverso per un Circle come per un Square e non è possibile risolverlo con un codice uniforme. Se c'è altro lavoro che la fabbrica sta facendo, oltre a gestire gli argomenti del costruttore che a suo avviso dovrebbero accadere in una fabbrica, è necessario postare questo alla tua domanda e indicare la difficoltà che stai riscontrando nel prendere in considerazione questo codice comune.

5

tutte le implementazioni devono prendere lo stesso numero di argomenti. ci sono opzioni

  • avere gli argomenti di aggiunta in fabbrica, quindi è sufficiente fornire il centro per esempio.
  • fare in modo che la fabbrica riprenda tutti gli argomenti anche se alcune fabbriche potrebbero ignorarne alcune.
  • avere un argomento di lunghezza variabile. per esempio. 'doppio ...' il problema con questo è il chiamante ha bisogno di sapere ciò che la fabbrica ha bisogno che sconfigge lo scopo di una fabbrica. A PARER MIO.
+0

Consiglieresti di andare con l'opzione 2 oggi? –

+0

Solo la prima opzione è disponibile in un modello di Factory astratta corretto. Un altro modo per fare in modo che Factory abbia entrambi i metodi CreateTriangle e CreateCircule, ma sembra essere ortogonale all'obiettivo OP. – SerG

Problemi correlati