Design Pattern [2] —— 工厂模式 +抽象工厂模式 Factory

工厂作用:

  创建者和调用者分离( " 解耦 " ==》开闭原则 

  可扩展性强

使用场景:

  FactoryBean ==》IOC

  日志门面框架slf4j:  private final static Logger logger = LoggerFactory.getLogger(HelloWord.class);

  JDK 的 Calendar (简单工厂)    Calendar calendar = Calendar.getInstance();

  JDBC的 Connection

分类:

  简单工厂

  工厂方法

  抽象工厂

符合的OOP原则:开闭原则、依赖倒转原则(针对接口,而不是针对实现)、迪米特法则(只与直接朋友通信)


我的Github里有源码,可以clone下来自己跑下:https://github.com/Yang2199/Design-Pattern/tree/master/src

〇、朴素new对象

首先写个接口:

public interface Car {
    void name();
}

然后implement两个类:

public class NIO implements Car {
    @Override
    public void name() {
        System.out.println("This is 蔚来汽车");
    }
}
public class Tesla implements Car {
    @Override
    public void name() {
        System.out.println("This is 特斯拉");
    }
}

然后写个测试类:

public class Test {
    public static void main(String[] args) {
        Car car1 = new Tesla();
        car1.name();

        Car car2 = new NIO();
        car2.name();
    }
}

这时候需要new出对象来,不高级,没有工厂自动化生产对象

一、静态工厂/ 简单工厂模式 (用的最多)

public class SimpleFactory {
    public static Car getCar(String car){
        if(car.equals("NIO")) return new NIO(); //简单工厂需要根据传参来判断需要生产的对象类型
        if(car.equals("Tesla")) return new Tesla();
        else return null;
    }
}

测试

public class Test {
    public static void main(String[] args) {
        CarFactory.getCar("NIO").name();  //进步是传参进去就好了,不用在这里new了
        CarFactory.getCar("Tesla").name();
    }
}

 这种方法也不好,不方便扩展,扩展的时候,还要改原来的代码。==》不满足 "开闭原则"

二、工厂方法 模式

加一层,为每个类型写一个new的工厂;

增加了代码量,但是符合OOP原则:开闭原则(新增功能不用改原来的代码)

public interface Factory {
    Car getCar();
}
public class TeslaFactory implements Factory{
    @Override
    public Car getCar() {
        return new Tesla();  //getCar调用Tesla()类的构造器
    }
}
public class NIOFactory implements Factory {
    @Override
    public Car getCar() {
        return new NIO();
    }
}

 

public class Test {
    public static void main(String[] args) {
        Car car1 = new TeslaFactory().getCar();
        car1.name();
        new NIOFactory().getCar().name();
    }
}

三、抽象工厂 模式

  抽象工厂("工厂的工厂")负责创建各个工厂,是一个超级工厂

 适用场景:m个工厂(“品牌”)* n种产品

例子:

 具体代码:

public interface Phone {
    void start();
    void shutdown();
    void call();
    void message();
}
public class HuaweiPhone implements Phone{
    @Override
    public void start() {
        System.out.println("开启华为手机");
    }

    @Override
    public void shutdown() {
        System.out.println("关闭华为手机");
    }

    @Override
    public void call() {
        System.out.println("华为打电话");
    }

    @Override
    public void message() {
        System.out.println("华为打电话");
    }
}
public class XiaomiPhone implements Phone{
    @Override
    public void start() {
        System.out.println("开启小米手机");
    }

    @Override
    public void shutdown() {
        System.out.println("关闭小米手机");
    }

    @Override
    public void call() {
        System.out.println("小米打电话");
    }

    @Override
    public void message() {
        System.out.println("小米打电话");
    }
}
public interface Router {
    void start();
    void shutdown();
    void wifi();
}
public class HuaweiRouter implements Router{
    @Override
    public void start() {
        System.out.println("打开华为路由器");
    }

    @Override
    public void shutdown() {
        System.out.println("关闭华为路由器");
    }

    @Override
    public void wifi() {
        System.out.println("华为wifi");
    }
}
public class XiaomiRouter implements Router{
    @Override
    public void start() {
        System.out.println("打开小米路由器");
    }

    @Override
    public void shutdown() {
        System.out.println("关闭小米路由器");
    }

    @Override
    public void wifi() {
        System.out.println("小米wifi");
    }
}

然后开始创建工厂:

public interface AbstractFactory {
    Phone phone();
    Router router();
}
public class HuaweiFactory implements AbstractFactory{

    @Override
    public Phone phone() {
        return new HuaweiPhone();
    }

    @Override
    public Router router() {
        return new HuaweiRouter();
    }
}
public class XiaomiFactory implements AbstractFactory{

    @Override
    public Phone phone() {
        return new XiaomiPhone();
    }

    @Override
    public Router router() {
        return new XiaomiRouter();
    }
}

Test:

public class Test {
    public static void main(String[] args) {
        System.out.println("======Huawei系列产品======");
        HuaweiFactory huaweiFactory = new HuaweiFactory();

        Phone phone = huaweiFactory.phone(); //实际生产的时候,分两层,第一层找具体factory,第二层找具体产品
        phone.call();
        phone.shutdown();

        Router router =huaweiFactory.router();
        router.wifi();

        System.out.println("======小米产品======");
        XiaomiFactory xiaomiFactory = new XiaomiFactory();

        Phone phone2= xiaomiFactory.phone();
        phone2.message();
    }
}

 

以上代码生成 Class Diagram:

特色:

  一个Factory作为一个产品簇,这样实际生产的时候,分两层,第一层找具体factory,第二层找具体产品

  增/删 新的品牌,无需更改原有代码;

  增/删 新的产品,对原有改动很小


简单工厂

 工厂:

 


3种工厂特色对比:

  

原文地址:https://www.cnblogs.com/qyf2199/p/14601703.html