web-dev-qa-db-fra.com

Factory in Java lorsque les objets concrets prennent différents paramètres de constructeur

J'essaie d'implémenter un modèle Factory en Java. J'ai une classe appelée Shape qui étend Circle et Triangle. Le problème est que le constructeur Shape n'obtient que 2 paramètres tandis que Circle obtient 3 paramètres, tout comme Triangle (que je ne montrerai pas dans la section de code car il est identique à Circle). Pour mieux le démontrer:

    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);
        }
    }

Des idées sur la façon de surmonter ce problème? Je ne dois pas recevoir une entrée de l'utilisateur à l'intérieur de l'usine (doit être reçue de l'extérieur).

Merci!

47
Jjang

Vous avez deux options:

1) sine abstraite :

RectangularShape extends Shape

RoundShape extends Shape

et RectangularShapeFactory et RoundShapeFactory

2) Builder (voir aussi le point 2 de Java efficace)

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();
31
m3th0dman

Ce que vous essayez de faire est tout simplement impossible. Si les arguments du constructeur sont différents, le code client devra effectuer un travail différent pour un Circle comme pour un Square et vous ne pouvez pas résoudre ce problème avec un code uniforme. S'il y a d'autres travaux que l'usine fait en plus de gérer les arguments du constructeur qui, selon vous, devraient se produire dans une usine, vous devez poster ceci à votre question et indiquer la difficulté que vous rencontrez pour factoriser ce travail de code commun.

8
djechlin

Toutes vos implémentations doivent prendre le même nombre d'arguments, vous avez trois options:

  • demandez à l'usine de stocker les arguments d'addition, vous n'avez donc qu'à fournir le centre par exemple.
  • demander à l'usine de prendre tous les arguments même si certaines usines peuvent ignorer certains d'entre eux.
  • avoir un argument de longueur variable. par exemple. 'double ...' le problème est que l'appelant a besoin de savoir ce dont l'usine a besoin, ce qui va à l'encontre du but d'une usine. A MON HUMBLE AVIS.
6
Peter Lawrey