01.工厂模式

工厂模式

工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

介绍

意图

工厂模式定义了一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行

优点

1、一个调用者想创建一个对象,只要知道其名称就可以了。

2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。

3、屏蔽产品的具体实现,调用者只关心产品的接口。

缺点

每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。

注意事项

作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要通过 new 就可以完成创建的对象,无需使用工厂模式。如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度。

Demo示例

简单工厂模式

我们将创建一个 Shape 接口和三个实现 Shape 接口的类。下一步是定义工厂类 SimpleFactoryPattern

FactoryPatternDemo 类使用 SimpleFactoryPattern来获取 Shape 对象。它将向 SimpleFactoryPattern传递信息(CIRCLE / RECTANGLE / SQUARE),以便获取它所需对象的类型。

在这里插入图片描述

  1. 首先我们创建一个Shape接口

    /**
     * @Author Christy
     * @Date 2021/4/20 14:44
     **/
    public interface Shape {
        void draw();
    }
    
  2. 创建Shape的三个实现类

    /**
     * @Author Christy
     * @Date 2021/4/20 14:51
     **/
    public class Circle implements Shape {
        @Override
        public void draw() {
            System.out.println("Inside Circle::draw() method!");
        }
    }
    
    /**
     * @Author Christy
     * @Date 2021/4/20 14:49
    **/
    public class Rectangle implements Shape {
        @Override
        public void draw() {
            System.out.println("Inside Rectangle::draw() method");
        }
    }
    
    /**
     * @Author Christy
     * @Date 2021/4/20 14:50
     **/
    public class Square implements Shape {
        @Override
    public void draw() {
            System.out.println("Inside Square::draw() method!");
        }
    }
    
  3. 定义类工厂SimpleFactoryPattern

    /**
     *
     * @Author Christy
     * @Date 2021/4/20 14:42
     **/
    public class SimpleFactoryPattern {
        public Shape getShape(String shapeType){
            if(!StringUtils.hasLength(shapeType)){
                return null;
            }
    
            if(shapeType.equalsIgnoreCase("Rectangle")){
                return new Rectangle();
            } else if(shapeType.equalsIgnoreCase("Square")){
                return new Square();
            } else if(shapeType.equalsIgnoreCase("Circle")){
                return new Circle();
            }
            return null;
        }
    }
    
  4. 编写测试代码FactoryPatternDemo

    /**
     * @Author Christy
     * @Date 2021/4/20 14:55
     **/
    public class FactoryPatternDemo {
        public static void main(String[] args){
            SimpleFactoryPattern simpleFactoryPattern =  new SimpleFactoryPattern();
    				/******************** 简单工厂模式 ********************/
            /** 获取 Rectangle 的对象,并调用它的draw方法 **/
            Shape shape01 = simpleFactoryPattern.getShape("RECTANGLE");
            shape01.draw();
    
            /** 获取 Circle 的对象,并调用它的draw方法 **/
            Shape shape02 = simpleFactoryPattern.getShape("CIRCLE");
            shape02.draw();
    
            /** 获取 Circle 的对象,并调用它的draw方法 **/
            Shape shape03 = simpleFactoryPattern.getShape("SQUARE");
            shape03.draw();
        }
    }
    
  5. 测试结果

    在这里插入图片描述

  6. 简单工厂存在的问题

    通过上面的代码我们可以发现一个问题:

    假如我先要增加一个Triangle该怎么办呢?首先我们需要定义一个类Triangle并继承Shape接口,像下面这样

    /**
     * @Author Christy
     * @Date 2021/4/21 14:39
     **/
    public class Triangle implements Shape {
        @Override
        public void draw() {
            System.out.println("Inside Triangle::draw() method!");
        }
    }
    

    这样还不行,我们需要进一步修改SimpleFactoryPattern来返回一个Triangle才可以,像这样

    /**
     *
     * @Author Christy
     * @Date 2021/4/20 14:42
     **/
    public class SimpleFactoryPattern {
        public Shape getShape(String shapeType){
            if(!StringUtils.hasLength(shapeType)){
                return null;
            }
    
            if(shapeType.equalsIgnoreCase("Rectangle")){
                return new Rectangle();
            } else if(shapeType.equalsIgnoreCase("Square")){
                return new Square();
            } else if(shapeType.equalsIgnoreCase("Circle")){
                return new Circle();
            } else if(shapeType.equalsIgnoreCase("Triangle")){
                return new Triangle();
            }
            return null;
        }
    }
    

    这样一来我们就发现该种写法违反了上一节00.认识设计模式中提到的6大设计原则中的第一条开闭原则(只对扩展开放,对修改关闭)。所以简单工厂模式所能创建的类只能是事先考虑到的,如果需要添加新的类,则就需要改变工厂类了

工厂模式

基于上述简单工厂存在的缺点,我们看下工厂模式是如何解决这些问题的

  1. 首先我们新建一个工厂模式接口类FactoryPattern

    /**
     * @Author Christy
     * @Date 2021/4/21 14:31
     **/
    public interface FactoryPattern {
        Shape createShapeFactory();
    }
    
  2. 新建RectangleFactoryCircleFactorySquareFactoryTriangleFactory四个工厂类分别实现上面定义的工厂模式类接口

    /**
     * @Author Christy
     * @Date 2021/4/21 15:01
     **/
    public class RectangleFactory implements FactoryPattern {
        @Override
        public Shape createShapeFactory() {
            return new Rectangle();
        }
    }
    
    /**
     * @Author Christy
     * @Date 2021/4/21 15:07
     **/
    public class CircleFactory implements FactoryPattern {
        @Override
        public Shape createShapeFactory() {
            return new Circle();
        }
    }
    
    /**
     * @Author Christy
     * @Date 2021/4/21 15:08
     **/
    public class SquareFactory implements FactoryPattern {
        @Override
        public Shape createShapeFactory() {
            return new Square();
        }
    }
    
    /**
     * @Author Christy
     * @Date 2021/4/21 15:09
     **/
    public class TriangleFactory implements FactoryPattern {
        @Override
        public Shape createShapeFactory() {
            return new Triangle();
        }
    }
    
  3. 修改Demo示例FactoryPatternDemo

    /**
     * @Author Christy
     * @Date 2021/4/20 14:55
     **/
    public class FactoryPatternDemo {
        public static void main(String[] args){
            SimpleFactoryPattern simpleFactoryPattern =  new SimpleFactoryPattern();
            /******************** 简单工厂模式 ********************/
            /** 获取 Rectangle 的对象,并调用它的draw方法 **/
            Shape shape02 = simpleFactoryPattern.getShape("RECTANGLE");
            shape02.draw();
    
            /** 获取 Circle 的对象,并调用它的draw方法 **/
            Shape shape01 = simpleFactoryPattern.getShape("CIRCLE");
            shape01.draw();
    
            /** 获取 Circle 的对象,并调用它的draw方法 **/
            Shape shape03 = simpleFactoryPattern.getShape("SQUARE");
            shape03.draw();
    
    
            /******************** 工厂模式 ********************/
            /** RectangleFactory 生成 Shape 类调用 Rectangle 的 draw 方法 **/
            RectangleFactory rectangleFactory =  new RectangleFactory();
            Shape rectangle = rectangleFactory.createShapeFactory();
            rectangle.draw();
    
            /** CircleFactory 生成 Shape 类调用 Circle 的 draw 方法 **/
            CircleFactory circleFactory = new CircleFactory();
            Shape circle = circleFactory.createShapeFactory();
            circle.draw();
    
            /** CircleFactory 生成 Shape 类调用 Circle 的 draw 方法 **/
            SquareFactory squareFactory = new SquareFactory();
            Shape square = squareFactory.createShapeFactory();
            square.draw();
        }
    }
    
  4. 测试结果

    在这里插入图片描述

由此可以看到工厂模式没有简单工厂中违反开闭原则的缺点,而且符合面向对象的多态性;较之于简单工厂模式有更好的扩展性。假如后期我们想增加一个Rhombus,我们只要新建一个RhombusFactory并实现FactoryPattern即可。

至此,工厂模式我们就学习完了!工厂模式是23中设计模式中最简单的一种设计模式,从工厂模式开始学习也是由易到难、由简至繁的过程,继续加油吧O(∩_∩)O哈哈~

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

潮汐先生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值