java - 抽象工厂模式支持什么样的业务背景
黄舟
黄舟 2017-04-18 09:27:40
0
1
693
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();
    }
}

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

黄舟
黄舟

人生最曼妙的风景,竟是内心的淡定与从容!

reply all(1)
大家讲道理

I think the question you asked is very meaningful. Many people cannot flexibly apply design patterns

Let me talk about why we should use the factory class design pattern from the perspective of analyzing the problem

Question 1: We often have classes with functions similar to , so our idea is to abstract them, use interfaces to expose public methods, and use abstract classes to provide public implementations.

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

Question 2: The instantiation of these classes with similar functions has become a problem. The constructor parameters of each class are different. It is very troublesome to new the object every time, so it is encapsulated into Simple Factory Pattern.

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

The third question: The simple factory model is not conducive to expansion and violates the opening and closing principle. Every time a class is added, the factory class must be modified (if the factory class and business class are written separately by two partners, then It doesn’t take a lot of time to communicate...), so there is the Factory Method Pattern, the principle of which is to abstract simple factories.

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 No. 4: Suddenly I found something bad, because the code has become a lot, because we have 3 layers of abstraction for products with similar functions, and for each product we have also abstracted 2 layers of factory classes. But in a specific business scenario, we don't just instantiate a class. For example, in the game, if we want a soldier to be equipped with equipment, first we need to equip him with a firearm (there are many firearms, such as rifles, sniper rifles, etc., use question 1 for abstraction), but after equipping the firearm, we also need to equip him with equipment. Bullets (continue to use the method of question 1 for abstraction), okay, now we can abstract the two-layer factory class. Based on the current situation, can we have a factory that produces both firearms and bullets? This is the Abstract Factory Pattern. To put it simply, you can put some related or similar products into one factory for production. There is no need to open a separate factory .

Also a correction, the code you posted is the factory method pattern, not the abstract factory pattern.


Seeing that the questioner has not accepted my answer, I will say a few more words and give a specific application case.

We all know that Java's generics are implemented using type erasure (generics are removed during the javac compilation process and forced type conversion is added). So we cannot instantiate an object directly with new T(). In fact, it can be solved by using the factory method patterndesign pattern.

Suppose we have a class that uses generic instantiation.

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

We give the factory interface as follows:

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

We can then use the following methods to improve it

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

At this time, we can instantiate Foo in the following way

new Foo(new Ifactory<Integer>(){
    Integer create(){
        return new Integer(0);
    }
});

new Foo(new Ifactory<String>(){
    String create(){
        return "Hello";
    }
});

ps: In order to avoid being too verbose, the implementation of the factory method is done here using internal classes.

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template