工厂模式

1 基本概念

1、本质

  • 实例化对象不使用new,用工厂方法代替。
  • 将选择实现类、创建对象统一管理和控制,从而将调用者与实现类解耦。

2、作用

  • 实现创建者和调用者的分离。

3、分类

  • 简单工厂模式:用来生产同一等级结构中的任意产品(对于增加新的产品,需要覆盖已有代码)。
  • 工厂方法模式:用来生产同一等级结构中的固定产品(支持增加任意产品)。
  • 抽象工厂模式:围绕一个超级工厂创建其他工厂。该工厂又称为其他工厂的工厂。

4、OOP七大原则

  • 开闭原则:一个软件的实体应当对扩展开放,对修改关闭。
  • 依赖倒转原则:要针对接口编程,不要针对实现编程。
  • 迪米特法则:只与直接的朋友通信,而避免和陌生人通信。

2 分类

1、简单工厂模式(静态工厂模式)

  • Car

    package factory.simple;
    
    public interface Car {
        void name();
    }
  • WuLing

    package factory.simple;
    
    public class WuLing implements Car {
        @Override
        public void name() {
            System.out.println("WuLing");
        }
    }
  • Tesla

    package factory.simple;
    
    public class Tesla implements Car {
        @Override
        public void name() {
            System.out.println("Tesla");
        }
    }
  • CarFactory

    package factory.simple;
    
    public class CarFactory {
        public static Car getCar(String car) {
            if ("WuLing".equals(car)) {
                return new WuLing();
            }
            if ("Tesla".equals(car)) {
                return new Tesla();
            }
            return null;
        }
    }
  • Consumer

    package factory.simple;
    
    import org.junit.Test;
    
    public class Consumer {
        @Test
        public void test() {
            // 1、使用new创建(需要知道接口,所有的实现类)
            Car car01 = new WuLing();
            Car car02 = new Tesla();
            car01.name();
            car02.name();
            // 2、使用工厂创建
            Car wuLing = CarFactory.getCar("WuLing");
            wuLing.name();
        }
    }
  • Dazhong(新增Car,需要同时修改CarFactory源码)

    package factory.simple;
    
    public class Dazhong implements Car {
        @Override
        public void name() {
            System.out.println("Dazhong");
        }
    }

2、工厂方法模式

  • Car

    package factory.simple;
    
    public interface Car {
        void name();
    }
  • WuLing

    package factory.simple;
    
    public class WuLing implements Car {
        @Override
        public void name() {
            System.out.println("WuLing");
        }
    }
  • Tesla

    package factory.simple;
    
    public class Tesla implements Car {
        @Override
        public void name() {
            System.out.println("Tesla");
        }
    }
  • CarFactory

    package factory.method;
    
    public interface CarFactory {
        Car getCar();
    }
  • WuLingFactory

    package factory.method;
    
    public class WuLingFactory implements CarFactory {
        @Override
        public Car getCar() {
            return new WuLing();
        }
    }
  • TeslaFactory

    package factory.method;
    
    public class TeslaFactory implements CarFactory {
        @Override
        public Car getCar() {
            return new Tesla();
        }
    }
  • MoBai(新增Car)

    package factory.method;
    
    public class MoBai implements Car {
        @Override
        public void name() {
            System.out.println("MoBai");
        }
    }
  • MoBaiFactory(提供相应的工厂)

    package factory.method;
    
    public class MoBaiFactory implements CarFactory {
        @Override
        public Car getCar() {
            return new MoBai();
        }
    }
  • Consumer

    package factory.method;
    
    import org.junit.Test;
    
    public class Consumer {
        @Test
        public void test() {
            Car car01 = new WuLingFactory().getCar();
            Car car02 = new TeslaFactory().getCar();
            car01.name();
            car02.name();
            Car car03 = new MoBaiFactory().getCar();
            car03.name();
        }
    }

3、抽象工厂模式

1、定义

  • 抽象工厂模式提供了创建一系列相关或者相互依赖对象的接口,无须指定它们具体的类。

2、适用场景

  • 客户端(应用层)不依赖于产品实例如何被创建、实现等细节。
  • 强调一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量重复的代码。
  • 提供一个产品类的库,所有的产品以同样的接口出现,从而使得客户端不依赖于具体的实现。

3、优点

  • 具体产品在应用层的代码隔离,无须关心创建的细节。
  • 将一个系列的产品统一到一起创建。

4、缺点

  • 规定了所有可能被创建的产品集合,产品簇中扩展新的产品困难。
  • 增加了系统的抽象性和理解难度。

5、代码

图片说明

  • IProductFactory

    package factory.abstract1;
    
       /**
        * 抽象产品工厂
        */
       public interface IProductFactory {
       // 生产手机
       IphoneProduct iphoneProduct();
    
       // 生产路由器
       IRouterProduct routerProduct();
       }
  • IphoneProduct

    package factory.abstract1;
    
       /**
        * 手机产品接口
        */
       public interface IphoneProduct {
       void start();
       void shutdown();
       void callup();
       void sendMS();
       }
  • IRouterProduct

    package factory.abstract1;
    
       /**
        * 路由器产品接口
        */
       public interface IRouterProduct {
           void start();
           void shutdown();
           void openWifi();
           void setting();
       }
  • XiaomiPhone

    package factory.abstract1;
    
    /**
     * 小米手机
     */
    public class XiaomiPhone implements IphoneProduct {
       @Override
       public void start() {
           System.out.println("开启小米手机");
       }
    
       @Override
       public void shutdown() {
           System.out.println("关闭小米手机");
       }
    
       @Override
       public void callup() {
           System.out.println("小米打电话");
       }
    
       @Override
       public void sendMS() {
           System.out.println("小米发短信");
       }
    }
  • XiaomiRouter

    package factory.abstract1;
    
    /**
     * 小米路由器
     */
    public class XiaomiRouter implements IRouterProduct {
       @Override
       public void start() {
           System.out.println("启动小米路由器");
       }
    
       @Override
       public void shutdown() {
           System.out.println("关闭小米路由器");
       }
    
       @Override
       public void openWifi() {
           System.out.println("打开小米Wifi");
       }
    
       @Override
       public void setting() {
           System.out.println("小米路由器设置");
       }
    }
  • HuaweiPhone

    package factory.abstract1;
    
    /**
     * 华为手机
     */
    public class HuaweiPhone implements IphoneProduct {
       @Override
       public void start() {
           System.out.println("开启华为手机");
       }
    
       @Override
       public void shutdown() {
           System.out.println("关闭华为手机");
       }
    
       @Override
       public void callup() {
           System.out.println("华为打电话");
       }
    
       @Override
       public void sendMS() {
           System.out.println("华为发短信");
       }
    }
  • HuaweiRouter

    package factory.abstract1;
    
    /**
     * 华为路由器
     */
    public class HuaweiRouter implements IRouterProduct {
       @Override
       public void start() {
           System.out.println("启动华为路由器");
       }
    
       @Override
       public void shutdown() {
           System.out.println("关闭华为路由器");
       }
    
       @Override
       public void openWifi() {
           System.out.println("打开华为Wifi");
       }
    
       @Override
       public void setting() {
           System.out.println("华为路由器设置");
       }
    }
  • XiaomiFactory

    package factory.abstract1;
    
    public class XiaomiFactory implements IProductFactory {
        @Override
        public IphoneProduct iphoneProduct() {
            return new XiaomiPhone();
        }
    
        @Override
        public IRouterProduct routerProduct() {
            return new XiaomiRouter();
        }
    }
  • HuaweiFactory

    package factory.abstract1;
    
    public class HuaweiFactory implements IProductFactory {
        @Override
        public IphoneProduct iphoneProduct() {
            return new HuaweiPhone();
        }
    
        @Override
        public IRouterProduct routerProduct() {
            return new HuaweiRouter();
        }
    }
  • Client

    package factory.abstract1;
    
    import org.junit.Test;
    
    public class Client {
        @Test
        public void test() {
            System.out.println("=====小米系列产品=====");
            // 小米工厂
            XiaomiFactory xiaomiFactory = new XiaomiFactory();
            IphoneProduct iphoneProduct = xiaomiFactory.iphoneProduct();
            iphoneProduct.callup();
            iphoneProduct.sendMS();
            IRouterProduct iRouterProduct = xiaomiFactory.routerProduct();
            iRouterProduct.openWifi();
            System.out.println("=====华为系列产品=====");
            // 华为工厂
            HuaweiFactory huaweiFactory = new HuaweiFactory();
            IphoneProduct iphoneProduct1 = huaweiFactory.iphoneProduct();
            iphoneProduct1.callup();
            IRouterProduct iRouterProduct1 = huaweiFactory.routerProduct();
            iRouterProduct1.openWifi();
        }
    }

3 小结

3.1 对比

1、简单工厂模式(静态工厂模式)

  • 虽然某种程度上不符合设计原则,但实际使用最多。

2、工厂方法模式

  • 不修改已有类的前提下,通过增加新的工厂类实现扩展。

3、抽象工厂模式

  • 不可以增加产品,可以增加产品族。

3.2 应用场景

  • JDK中的Calendar、Connection。
  • Spring中IOC容器创建管理Bean对象。
  • 反射中Class对象的newInstance方法。
全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务