• 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种工厂特色对比:

      

  • 相关阅读:
    C# GridView使用 与 DataList分页。
    如何禁止服务器端口 135 137 3389等
    页面自动刷新 与 隔时刷新
    彻底解决网页图片只能另存为无标题bmp位图
    C# Byte[]数组转化为string类型.其实很简单.
    vs2003打开时报错。尝试创建 Web 项目或打开位于..
    Discuz! 在线人数,发帖数,修改。
    点击文本框出现时间选择器DateJs
    一张有转折意义的神秘地图
    中断异常的处理
  • 原文地址:https://www.cnblogs.com/qyf2199/p/14601703.html
Copyright © 2020-2023  润新知