recherche

Maison  >  Questions et réponses  >  le corps du texte

java - 抽象工厂模式支持什么样的业务背景

package GOF;

interface Create {

    public void create();
}

class A implements Create {

    @Override
    public void create() {
        System.out.println("A");
    }
}

class B implements Create {

    @Override
    public void create() {
        System.out.println("B");
    }
}

interface Produce {

    public Create produce();
}

class C implements Produce {

    @Override
    public Create produce() {
        return new A();
    }
}

class D implements Produce {

    @Override
    public Create produce() {
        return new B();
    }
}

public class AbstractFactory {

    public static void main(String[] args) {
        Produce produce = new C();
        Create create = produce.produce();
        create.create();
    }
}

如上图所示代码,是抽象工厂模式的实例。请问在实际的业务场景中如何使用?有什么优点。

黄舟黄舟2785 Il y a quelques jours700

répondre à tous(1)je répondrai

  • 大家讲道理

    大家讲道理2017-04-18 09:29:40

    Je pense que la question que vous avez posée est très significative. De nombreuses personnes ne peuvent pas appliquer de manière flexible les modèles de conception

    .

    Permettez-moi d'expliquer pourquoi nous devrions utiliser le modèle de conception de classe usine du point de vue de l'analyse du problème

    Question 1 : Nous avons souvent des classes avec des fonctions similaires à , notre idée est donc de les abstraire, d'utiliser des interfaces pour exposer les méthodes publiques et d'utiliser des classes abstraites pour fournir une réalisation publique .

    public interface IProduct {
        void print(); // 这是要暴露的方法
    }
    
    public abstract class AbstractProduct implements IProduct {
        protected void printBefore(){
            System.out.println("before print"); // 这里所公共的实现
        }
    }
    
    public class AProduct extends AbstractProduct {
        private String name;
        public AProduct(String name){ 
            this.name = name;
        }
        @Override
        public void print() {
            this.printBefore();
            System.out.println("print A >>>"+name);
        }
    }
    
    public class BProduct extends AbstractProduct {
        private String name;
        public BProduct(String name){ 
            this.name = name;
        }
        @Override
        public void print() {
            this.printBefore();
            System.out.println("print B >>>"+name);
        }
    }

    La deuxième question : L'instanciation de ces classes avec des fonctions similaires est devenue un problème. Les paramètres du constructeur de chaque classe sont différents. Il est difficile de renouveler l'objet à chaque fois, il est donc encapsulé dans une simple usine. modèle.

    public class SimpleFactory {
        public static IProduct getProduct(String name){
            if("A".equals(name)){
                return new AProduct(name);
            }else if("B".equals(name)){
                return new BProduct(name);
            }else{
                throw new IllegalArgumentException();
            }
        }
    }

    La troisième question : Le modèle d'usine simple n'est pas propice à l'expansion et viole le principe d'ouverture et de fermeture À chaque fois qu'une classe est ajoutée, la classe d'usine doit être modifiée (si la classe d'usine et la classe d'usine. la classe affaires sont deux petits Si les partenaires l'écrivent séparément, ça ne prend pas beaucoup de temps pour communiquer...), il y a donc le Factory Method Pattern dont le principe est d'abstraire un usine simple.

    public interface IFactory {
        IProduct getProduct();
    }
    
    public class AFactory implements IFactory {
        @Override
        public IProduct getProduct() {
            return new AProduct(AProduct.class.getName());
        }
    }
    
    public class BFactory implements IFactory {
        @Override
        public IProduct getProduct() {
            return new BProduct(BProduct.class.getName());
        }
    }

    Question 4 : Du coup, j'ai trouvé quelque chose de mauvais, car le code est devenu beaucoup, car nous avons 3 couches d'abstraction pour les produits avec des fonctions similaires, et nous avons également abstrait 2 couches de classes d'usine pour chaque produit. Mais dans un scénario métier spécifique, nous ne nous contentons pas d’instancier une classe. Par exemple, dans le jeu, si l'on veut qu'un soldat soit équipé d'équipement, il faut d'abord l'équiper d'une arme à feu (il existe de nombreuses armes à feu, comme les fusils, les fusils de sniper, etc., utilisez la question 1 pour faire abstraction), mais après avoir équipé l'arme à feu, nous devons également l'équiper de balles (continuez à utiliser la méthode de la question 1 pour l'abstraction), d'accord, pouvons-nous maintenant faire abstraction de la classe d'usine à deux couches. avez-vous une usine qui produit à la fois des armes à feu et des balles ? Il s’agit du Modèle d’usine abstrait. Pour faire simple, vous pouvez regrouper certains produits connexes ou similaires dans une seule usine pour la production. Il n'est pas nécessaire d'ouvrir une usine distincte .

    Aussi pour me corriger, le code que vous avez publié est le modèle de méthode d'usine, pas le modèle d'usine abstrait.


    Voyant que la personne qui a posé la question n'a pas accepté ma réponse, je vais dire quelques mots supplémentaires et donner un cas de candidature précis.

    Nous savons tous que les génériques de Java sont implémentés en utilisant l'effacement de type (les génériques sont supprimés pendant le processus de compilation javac et une conversion de type forcée est ajoutée). Nous ne pouvons donc pas instancier un objet directement avec new T(). En fait, cela peut être résolu en utilisant le modèle de conception Factory Method Pattern.

    Supposons que nous ayons une classe qui utilise l'instanciation générique.

    public class Foo<T>(){
        private T t;
        public Foo(){
           t = new T(); // 这个代码是有问题的,我们使用工厂设计模式进行改进
        }
    }

    Nous donnons l'interface d'usine comme suit :

    public interface IFactory<T>(){
        T create();
    }

    Nous pouvons ensuite utiliser les méthodes suivantes pour l'améliorer

    public class Foo<T>(){
        private T t;
        public <F extends IFactory<T>> Foo(F factory){
            // t = new T(); 
            factory.create();       
        }
    }

    A ce moment, nous pouvons instancier Foo

    de la manière suivante
    new Foo(new Ifactory<Integer>(){
        Integer create(){
            return new Integer(0);
        }
    });
    
    new Foo(new Ifactory<String>(){
        String create(){
            return "Hello";
        }
    });

    ps : Afin d'éviter d'être trop verbeux, l'implémentation de la méthode factory se fait ici à l'aide de classes internes.

    répondre
    0
  • Annulerrépondre