23种设计模式之工厂模式

23种设计模式之工厂模式(Factory Pattern)

创建型设计模式

意图: 隐藏复杂对象的创建逻辑,统一管理复杂对象的生成。

这里强调复杂对象是因为,简单的对象生成完全不需要通过工厂类来生成。直接通过简单的new即可。
过度的滥用设计模式会造成系统的臃肿

优点:

  1. 屏蔽产品的实现,调用者只关心产品的接口
  2. 扩展性高,如果想增加一个产品,只要拓展改变工厂即可

缺点:

1. 每次增加产品时,都需要增加一个类和对象的实现工厂,系统中的类会成倍的增加,造成系统过于庞大。

1. 简单工厂模式

1.1 简单工厂中包含的角色

  1. 工厂类 (提供一个返回抽象类类型的方法,方法参数接收具体类的类型,根据类型返回具体类)
  2. 抽象类接口
  3. 具体类(实现抽象类接口)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W8MqzvKx-1641915842222)(C:\Users\wddong\AppData\Roaming\Typora\typora-user-images\image-20220111234151255.png)]

1.2 简单工厂的代码实现

//简单工厂

public interface Shape {
    void draw();
}
public class ShapeImplOne implements Shape {
    @Override
    public void draw() {
        System.out.println("shapeImplOne run");
    }
}
public class ShapeImplTwo implements Shape {
    @Override
    public void draw() {
        System.out.println("shapeImplTwo run");
    }
}
public class ShapeFactory {

    public static Shape getShape(String shape){
        if (StringUtils.isEmpty(shape)){
            return null;
        }
        if (shape.equals("shapeImplOne")){
            return new ShapeImplOne();
        }else if (shape.equals("shapeImplTwo")){
            return new ShapeImplTwo();
        }
        return null;
    }
}
public class ShapeFactoryTest {
    public static void main(String[] args) {
        Shape shapeImplOne = ShapeFactory.getShape("shapeImplOne");
        shapeImplOne.draw();
        Shape shapeImplTwo = ShapeFactory.getShape("shapeImplTwo");
        shapeImplTwo.draw();
        Shape shapeImpl = ShapeFactory.getShape("");
        shapeImpl.draw();
    }
}

1.3 简单工厂的优缺点分析

简单工厂由于使用if else 判断,增加一个产品时,不需要增加对象的实现工厂,在else if 里面 可以直接创建。不会造成系统中类过于臃肿的情况。由于简单工厂每次新增一个产品子项,都需要在工厂类中去修改代码,违背了开闭原则。


2. 抽象工厂模式

围绕一个超级工厂建造其他的工厂,该工厂又称为其他工厂的工厂。在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显示的指定他们的类,每个生成的工厂都能按照那工厂模式提供对象。

2.1 抽象工厂中包含的角色

  1. 抽象工厂
  2. 抽象工厂的实现类
  3. 抽象产品
  4. 抽象产品的实现类

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t8mASPa7-1641915842224)(C:\Users\wddong\AppData\Roaming\Typora\typora-user-images\image-20220111234226603.png)]

2.2 抽象工厂的简单代码实现

//抽象工厂

public interface Shape {
    void draw();
}
public class ShapeImplOne implements Shape {
    @Override
    public void draw() {
        System.out.println("shapeImplOne run");
    }
}
public class ShapeImplTwo implements Shape {
    @Override
    public void draw() {
        System.out.println("shapeImplTwo run");
    }
}
public interface ShapeFactory {
    Shape getShape();
}

public class ShapeFactoryA implement ShapeFactory {
    @Override
    public Shape getShape() {
        return new ShapeImplOne();
    }
}

public class ShapeFactoryB implement ShapeFactory {
    @Override
    public Shape getShape() {
        return new ShapeImplTwo();
    }
}
public class ShapeFactoryTest {
    public static void main(String[] args) {
        ShapeFactory factory = new ShapeFactoryB();
	    Shape shapeB = factory.getShape();
        shapeB.draw();
    }
}

2.3 抽象工厂的优缺点分析

抽象工厂和工厂方法实际上是同一种东西,抽象工厂是工厂方法的延续。解决了简单工厂违背开闭原则的问题。但是新增产品时,容易造成系统中类过于臃肿的情况


3. 抽象工厂的案例分析

假设我们现在有一个需求,形状有圆形和方形,在形状的基础上又有红色和蓝色。

3.1 实现方式一:(颜色抽象工厂)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TMBOxBGh-1641915842224)(C:\Users\wddong\AppData\Roaming\Typora\typora-user-images\image-20220111225242416.png)]

3.1.1 代码实现

public interface Shape {
    void draw();
}

public abstract class Circle implements Shape {

}

public abstract class Rectangle implements Shape {

}

public class RedCircle extends Circle {

    @Override
    public void draw() {
        System.out.println("Red Circle");
    }
}

public class BuleCircle extends Circle {

    @Override
    public void draw() {
        System.out.println("Bule Circle");
    }
}

public class RedRectangle extends Rectangle {

    @Override
    public void draw() {
        System.out.println("Red Rectangle");
    }
}

public class BuleRectangle extends Rectangle {

    @Override
    public void draw() {
        System.out.println("Bule Rectangle");
    }
}

public interface ShapeFactory {
    Shape getCircle();

    Shape getRectangle();
}

public class RedShapeFactory implements ShapeFactory {

    @Override
    public Shape getCircle() {
        return new RedCircle();
    }

    @Override
    public Shape getRectangle() {
        return new RedRectangle();
    }
}

public class BuleShapeFactory implements ShapeFactory {

    @Override
    public Shape getCircle() {
        return new BuleCircle();
    }

    @Override
    public Shape getRectangle() {
        return new BuleRectangle();
    }
}
public class Test{
    public static void main(String[] args) {
        BuleShapeFactory shapeFactory = new BuleShapeFactory();
        Shape shape = shapeFactory.getRectangle();
        shape.draw();
    }
}


3.2 实现方式二:(形状抽象工厂)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存失败,源站可能有防盗链机制,建议将图片保存下来直接上传上传(imuNx2LcUWXp-1641915842225)(C:\Users\wddong\AppData\Roaming\Typora\typora-user-images\image-20220111230005979.png)(C:\Users\wddong\AppData\Roaming\Typora\typora-user-images\image-20220111230005979.png)]

3.2.1 代码实现

public interface Shape {
    void draw();
}

public abstract class RedShape implements Shape {

}

public abstract class BuleShape implements Shape {

}

public class RedCircle extends RedShape {

    @Override
    public void draw() {
        System.out.println("Red Circle");
    }
}
public class RedRectangle extends RedShape {

    @Override
    public void draw() {
        System.out.println("Red Rectangle");
    }
}

public class BuleCircle extends BuleShape {

    @Override
    public void draw() {
        System.out.println("Bule Circle");
    }
}

public class BuleRectangle extends BuleShape {

    @Override
    public void draw() {
        System.out.println("Bule Rectangle");
    }
}

public interface ColorFactory {
    Shape getRed();

    Shape getBule();
}

public class CircleColorFactory implements ColorFactory {

    @Override
    public Shape getRed() {
        return new RedCircle();
    }

    @Override
    public Shape getBule() {
        return new BuleCircle();
    }
}

public class RectangleColorFactory implements ColorFactory {
    @Override
    public Shape getRed() {
        return new RedRectangle();
    }

    @Override
    public Shape getBule() {
        return new BuleRectangle();
    }
}
public class Test{
    public static void main(String[] args) {
        ColorFactory colorFactory = new CircleColorFactory();
        Shape shape = colorFactory.getRed();
        shape.draw();
    }
}

3.3 实现方式对比

实际场景中的业务非常多变,

  1. 当我们有新的产品是绿色的圆形时

实现方式一只需要添加一个新的GreenShapeFactory即可完成拓展,不需要改变原有的代码。

实现方式二需要在原有的工厂类上进行改动,添加一个新的 Shape getGreen(); 这样的方式显然不符合开闭原则

2. 当我们有新的产品是红色的三角形时

实现方式一需要在原有的工厂类上进行改动,添加一个新的 Shape getTriangle(); 这样的方式显然不符合开闭原则

实现方式一只需要添加一个新的TriangleColorFactory即可完成拓展,不需要改变原有的代码。

通过上述的对比我们可以得知,在采用工厂模式来进行设计时,我们需要清晰的了解到我们业务需要拓展的方向,选择合适的方式来进行搭建,这样才能写出更优秀的代码


4. 为什么不在类的构造函数中,封装创建的逻辑,反而非要采用工厂类来实现呢?

创建一个复杂对象的过程中,我们可能会需要做到很多初始化的工作,(可能会是一段很长的代码,甚至包含数据库的查询操作)如果我们将这些代码全部封装到构造函数中,会造成构造函数过于臃肿,而且也不符合 Java 面向对象的(封装,分派)原则。

Q: 面向对象的封装和分派原则讲的是什么?
尽量将很长的代码“分割”成多段,将每段再封装起来(减少段与段直接的耦合),这样就能将风险打散。以后需要修改时,只需要修改某段,不会在发生牵一发动全身的事情。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

王叮咚

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

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

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

打赏作者

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

抵扣说明:

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

余额充值