java设计模式——创建型之工厂三兄弟(1)

来源:互联网 发布:js data- 编辑:程序博客网 时间:2024/05/15 16:41
自大学课程初识设计模式以来,就越发觉得有必要系统学习一下设计模式。刚好在实习前准备期间课比较少,抽出一点时间整理一下记一些笔记,复制粘贴比较多。笔记比较适合学习过设计模式的同学。

Simple Factory Pattern(简单工厂模式)

学习链接:极客学院Wiki_Java设计模式之创造型模式


简单工厂模式的适用范围

(1) 工厂类负责创建的对象比较少,由于创建的对象较少,不会造成工厂方法中的业务逻辑太过复杂。

反映到代码上就是Factory类逻辑要简单就要创建对象少

(2) 客户端只知道传入工厂类的参数,对于如何创建对象并不关心。

顾客不应该知道产品是如何做的,只需要知道自己需要的产品的名字。


简单工厂模式如何实现

角色

Factory(工厂角色)

工厂角色即工厂类,它是简单工厂模式的核心,负责实现创建所有产品实例的内部逻辑;工厂类可以被外界直接调用,创建所需的产品对象;在工厂类中提供了静态的工厂方法 factoryMethod(),它的返回类型为抽象产品类型 Product。

Product(抽象产品角色)

它是工厂类所创建的所有对象的父类,封装了各种产品对象的公有方法,它的引入将提高系统的灵活性,使得在工厂类中只需定义一个通用的工厂方法,因为所有创建的具体产品对象都是其子类对象。

ConcreteProduct(具体产品角色)

它是简单工厂模式的创建目标,所有被创建的对象都充当这个角色的某个具体类的实例。每一个具体产品角色都继承了抽象产品角色,需要实现在抽象产品中声明的抽象方法。

类图

这里写图片描述
可以看到类图中除了上述,在Factory类中还有一个方法用于根据客户端参数返回产品对象,因此客户端只需要提供参数而不使用new XXX来创造产品。

当然Factory类有时也可以与Product类结合成一个类
这里写图片描述


简单工厂模式的优缺点

主要优点

(1) 工厂类包含必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的职责,而仅仅“消费”产品,简单工厂模式实现了对象创建和使用的分离。

(2) 客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于一些复杂的类名,通过简单工厂模式可以在一定程度减少使用者的记忆量。

(3) 通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。

主要缺点

(1) 由于工厂类集中了所有产品的创建逻辑,职责过重,一旦不能正常工作,整个系统都要受到影响。

(2) 使用简单工厂模式势必会增加系统中类的个数(引入了新的工厂类),增加了系统的复杂度和理解难度。

(3) 系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护。

(4) 简单工厂模式由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构。(这一点其实我不是很懂,有懂的朋友教我一下吗?)


练习

题目

使用简单工厂模式设计一个可以创建不同几何形状(如圆形、方形和三角形等)的绘图工具,每个几何图形都具有绘制 draw() 和擦除 erase() 两个方法,要求在绘制不支持的几何图形时,提示一个 UnSupportedShapeException。

实现代码

抽象产品:Shape.java

package com.joy;public abstract class Shape {    public abstract void draw();    public abstract void erase();}

具体产品:Circle.java

package com.joy;public class Circle extends Shape{    @Override    public void draw() {        System.out.println("绘制圆形");    }    @Override    public void erase() {        System.out.println("擦除圆形");    }}

具体产品:Rectangle.java

package com.joy;public class Rectangle extends Shape{    @Override    public void draw() {        System.out.println("绘制长方形");    }    @Override    public void erase() {        System.out.println("擦除长方形");    }}

具体产品:Triangle.java

package com.joy;public class Triangle extends Shape{    @Override    public void draw() {        System.out.println("绘制三角形");    }    @Override    public void erase() {        System.out.println("擦除三角形");    }}

工厂类:Factory.java

这个地方有一点不好,为了图方便把UnSupportedShapeException类写在这个方法里了,应该独立分开的。

package com.joy;public class Factory {    public static Shape getShape(String shapeName) throws UnSupportedShapeException{        if(shapeName.equals("Circle"))        return new Circle();        else if(shapeName.equals("Rectangle"))            return new Rectangle();        else if(shapeName.equals("Triangle"))            return new Triangle();        else            throw new UnSupportedShapeException();    }}class UnSupportedShapeException extends Exception{}

客户端:SimpleFactoryDemo.java

package com.joy;public class SimpleFactoryDemo {    public static void main(String[] args) {        Factory f = new Factory();        try {            System.out.println("*获取指定形状");            Shape shape = f.getShape("Circle");//圆形            System.out.println("*控制绘制");            shape.draw();            System.out.println("*控制擦除");            shape.erase();                  System.out.println("*获取指定形状");            Shape shape1 = f.getShape("Square");//正方形,没有该形状        } catch (UnSupportedShapeException e) {            e.printStackTrace();        }           }}

运行结果

这里写图片描述

总结

简单工厂虽然把产品都独立出来,将创建和调用分开了,但是Factory方法变得复杂和不灵活,应该改进。

0 0
原创粉丝点击