【设计模式系列】创建型之工厂方法模式 Factory Method Pattern

209 阅读3分钟

科学而且完美的解释(虽然很晦涩难懂)

定义一个(工厂)接口,具体对象创建封装到其子类中,这样核心类就变成一个接口而不是具体的实现类,同时可以在不修改具体实现类的情况下新增新的实现子类。工厂方法模式更符合开闭原则。

工厂方法模式是属于工厂模式中的一种,工厂模式细化可以有三种:简单工厂(可看作是工厂方法的一个特例),工厂方法,抽象工厂

常用的一般都是工厂方法,抽象工厂很少会用到简单了解一下就可以了

简单工厂

//简单工厂类
public class SimpleFactory {
    public static Man loadMan(String character) {
        Man man = null;
        if ("black".equalsIgnoreCase(character)) {
            man = new BlackMan();
        } else if ("white".equalsIgnoreCase(character)) {
            man = new WhiteMan();
        }
        return man;
    }
}
//人抽象接口
public interface Man {
    void talk();
}
//白人实现子类
public class WhiteMan implements Man {
    @Override
    public void talk() {
        System.out.println("whiteMan talk");
    }
}

//黑人实现子类
public class BlackMan implements Man {
    @Override
    public void talk() {
        System.out.println("blackMan talk");
    }
}

//调用测试
public class ChooseMan {
    public static void main(String[] args) {
        //不用设计模式
        Man man = null;
        String character = getCharacter();
        if ("black".equalsIgnoreCase(character)) {
            man = new BlackMan();
        } else if ("white".equalsIgnoreCase(character)) {
            man = new WhiteMan();
        }
        assert man != null;
        man.talk();
        System.out.println("-------------");
        //简单工厂模式
        SimpleFactory.loadMan(character).talk();
        System.out.println("---------");
    }

    private static String getCharacter() {
        return "black";
    }
}

在不使用设计模式时,我们if-else逻辑判断会写在调用的逻辑中,以后要修改就必须修改这边的逻辑,增加风险。简单工厂模式就是将if-else的代码封装成独立的类,避免修改时需要修改调用方的代码。但是简单工厂模式也不符合开闭原则,但是如果简单工厂if-else代码不需要经常改变的话,不符合开闭原则有时候也是可以接受的。

工厂方法模式

一个总的工厂接口,每个子类都是独立的,只需要新增子类就可以进行扩展,工厂方法模式更符合开闭原则

工厂方法模式可以去掉简单工厂模式中if-else判断,只需要针对每种情况都新建一个子类,在不同的情况下new不同的子类就行了。

//工厂接口
public interface ManFactory {
    Man createMan();
}
//具体工厂实现
public class WhiteManFactory implements ManFactory {
    @Override
    public Man createMan() {
        return new WhiteMan();
    }
}
public class BlackManFactory implements ManFactory {
    @Override
    public Man createMan() {
        return new BlackMan();
    }
}
//调用
public class ChooseMan {
    public static void main(String[] args) {
        //工厂方法模式:缺点判断逻辑又回到了调用方中
        ManFactory manFactory = null;
        if ("black".equalsIgnoreCase(character)) {
            manFactory = new BlackManFactory();
        } else if ("white".equalsIgnoreCase(character)) {
            manFactory = new WhiteManFactory();
        }
        assert manFactory != null;
        manFactory.createMan().talk();
    }

    private static String getCharacter() {
        return "black";
    }
}

如何使用这些工厂类是个问题,创建这些工厂类的代码有需要if-else写在调用的逻辑中,这就和最初不使用设计模式的代码很像了。 这时候可以写一个简单工厂,用于创建具体的实现工厂子类,就是把创建不同具体实现工厂的if-else判断写到简单工厂中。这就是简单工厂和工厂方法模式的组合使用。

抽象工厂模式

为创建一组相关或相互依赖的对象提供一个接口,而且无须指定它们的具体类,可以理解为工厂方法的升级版。

抽象工厂可以看作是对工厂方法模式的一种组合,以前工厂方法模式只创建一种类型的对象,而使用抽象工厂,一个工厂可以创建多种类型的对象。扩展了工厂方法模式。 直白简单讲,就是一个工厂类有多个创建不同对象的方法,通常情况下,这个工厂类创建的对象都有一定的关联,比如电脑工厂能创建显卡,主板之类的对象。