工厂模式(Factory)

简介: 工厂模式是创建型设计模式,它提供了一种创建对象的最佳方式。在工厂模式中,创建对象不会对客户端暴露创建逻辑,隐藏创建对象的详情,从而实现客户端与具体实现的解耦。工厂模式设计时需求注意的点:工厂类提供公共的方法来创建对象,无论静态,而不是客户端直接创建方法的参数可选,但参数只用来决定哪种实现,不应该存在业务参数方法的返回一般是被创建的接口对象,也可以是抽象类或具体类常见的工厂模式有工厂方法模式、简单工厂模式和抽象工厂模式等,并不要拘泥于哪种,在实际业务中根据需求设计。


一、概述



工厂模式是创建型设计模式,它提供了一种创建对象的最佳方式。在工厂模式中,创建对象不会对客户端暴露创建逻辑,隐藏创建对象的详情,从而实现客户端与具体实现的解耦。工厂模式设计时需求注意的点:

  • 工厂类提供公共的方法来创建对象,无论静态,而不是客户端直接创建
  • 方法的参数可选,但参数只用来决定哪种实现,不应该存在业务参数
  • 方法的返回一般是被创建的接口对象,也可以是抽象类或具体类

常见的工厂模式有工厂方法模式、简单工厂模式和抽象工厂模式等,并不要拘泥于哪种,在实际业务中根据需求设计。


二、工厂方法



工厂方法模式(Factory Method)定义一个用于创建对象的接口,让子类决定实例化哪一个类,使一个类的实例化延迟到其子类。在代码中,使用不同的工厂子类创建不同的对象,创建对象的细节封装在子类中。比如我们使用工厂方法来实现绘制不同形状的图形。

微信图片0001.jpg

定义一个 Shape 接口,并添加实现类,编写示例代码如下:

// Shape.java
public interface Shape {
    void draw();
}
// Circle.java
public class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("Circle.draw");
    }
}
// Rectangle.java
public class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("Rectangle.draw");
    }
}
// Square.java
public class Square implements Shape {
    @Override
    public void draw() {
        System.out.println("Square.draw");
    }
}

针对 Shape 接口定义一个抽象工厂类 ShapeFactory,并添加各个实例类的工厂子类,编写代码如下:

// ShapeFactory.java
public abstract class ShapeFactory {
    public void operate() {
        Shape shape = factoryMethod();
        shape.draw();
    }
    // 将创建对象的细节交给子类
    protected abstract Shape factoryMethod();
}
// CircleFactory.java
public class CircleFactory extends ShapeFactory {
    @Override
    protected Shape factoryMethod() {
        return new Circle();
    }
}
// RectangleFactory.java
public class RectangleFactory extends ShapeFactory {
    @Override
    protected Shape factoryMethod() {
        return new Rectangle();
    }
}
// SquareFactory.java
public class SquareFactory extends ShapeFactory {
    @Override
    protected Shape factoryMethod() {
        return new Square();
    }
}

编写主方法类,运行示例代码:

// Main.java
public class Main {
    public static void main(String[] args) {
        new CircleFactory().operate();
        new RectangleFactory().operate();
        new SquareFactory().operate();
    }
}


三、简单工厂



简单工厂模式(Factory)定义用于创建对象的类,客户端调用工厂类方法(静态或非静态)根据参数类型创建不同的对象实例,从而使得客户端和实现之间解耦。比如我们使用简单静态工厂来绘制不同形状的图形。

微信图片0002.png

定义一个工厂类,添加静态方法来根据类型创建不同实例,编写代码如下:

public class ShapeFactory {
    public static Shape getShape(String shapeType) {
        if ("CIRCLE".equalsIgnoreCase(shapeType)) {
            return new Circle();
        }
        if ("RECTANGLE".equalsIgnoreCase(shapeType)) {
            return new Rectangle();
        }
        if ("SQUARE".equalsIgnoreCase(shapeType)) {
            return new Square();
        }
        return null;
    }
}

编写主方法类,运行示例代码:

public class Main {
    public static void main(String[] args) {
        Shape circle = ShapeFactory.getShape("CIRCLE");
        circle.draw();
        Shape rectangle = ShapeFactory.getShape("RECTANGLE");
        rectangle.draw();
        Shape square = ShapeFactory.getShape("SQUARE");
        square.draw();
    }
}

简单工厂与工厂方法不一样的地方是简单工厂是客户端根据方法的参数类型来创建不同的对象。参数类型可以是整型数据、字符串等基本数据类型,也可以是枚举或其他类型,只要可以区分创建对象的实例类型就行,我们也可以利用环境配置,或者某个 Profile 来确定创建的对象实例,以达到兼容的目的。


四、抽象工厂



微信图片0003.png

抽象工厂模式(Abstract Factory)和工厂模式很相似,抽象工厂对工厂类进行了一层抽象,抽象的工厂类(超级工厂)可以创建其他工厂。比如我们基于前面的例子绘制不同形状的图形,并且给图形填充不同的颜色

定义一个 Color 颜色接口,并添加实现类,编写示例代码如下:

// Color.java
public interface Color {
    void fill();
}
// Red.java
public class Red implements Color {
    @Override
    public void fill() {
        System.out.println("Red.fill");
    }
}
// Green.java
public class Green implements Color {
    @Override
    public void fill() {
        System.out.println("Green.fill");
    }
}
// Blue.java
public class Blue implements Color {
    @Override
    public void fill() {
        System.out.println("Blue.fill");
    }
}

定义一个抽象工厂,并添加形状和颜色的实现工厂类,编写代码如下:

// AbstractFactory.java
public abstract class AbstractFactory {
    public abstract Color getColor(String color);
    public abstract Shape getShape(String shape);
}
// ShapeFactory.java
public class ShapeFactory extends AbstractFactory {
    @Override
    public Shape getShape(String shape) {
        if ("CIRCLE".equalsIgnoreCase(shape)) {
            return new Circle();
        } else if ("RECTANGLE".equalsIgnoreCase(shape)) {
            return new Rectangle();
        } else if ("SQUARE".equalsIgnoreCase(shape)) {
            return new Square();
        }
        return null;
    }
    @Override
    public Color getColor(String color) {
        return null;
    }
}
// ColorFactory.java
public class ColorFactory extends AbstractFactory {
    @Override
    public Color getColor(String color) {
        if ("RED".equalsIgnoreCase(color)) {
            return new Red();
        } else if ("GREEN".equalsIgnoreCase(color)) {
            return new Green();
        } else if ("BLUE".equalsIgnoreCase(color)) {
            return new Blue();
        }
        return null;
    }
    @Override
    public Shape getShape(String shape) {
        return null;
    }
}

定义超级工厂类,用于生产工厂类,编写代码如下:

// FactoryProducer.java
public class FactoryProducer {
    public static AbstractFactory getFactory(String choice) {
        if ("SHAPE".equalsIgnoreCase(choice)) {
            return new ShapeFactory();
        } else if ("COLOR".equalsIgnoreCase(choice)) {
            return new ColorFactory();
        }
        return null;
    }
}

编写主方法类,运行示例代码

// Main.java
public class Main {
    public static void main(String[] args) {
        AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE");
        Shape shape;
        shape = shapeFactory.getShape("CIRCLE");
        shape.draw();
        shape = shapeFactory.getShape("RECTANGLE");
        shape.draw();
        shape = shapeFactory.getShape("SQUARE");
        shape.draw();
        AbstractFactory colorFactory = FactoryProducer.getFactory("COLOR");
        Color color;
        color = colorFactory.getColor("RED");
        color.fill();
        color = colorFactory.getColor("GREEN");
        color.fill();
        color = colorFactory.getColor("BLUE");
        color.fill();
    }
}

抽象工厂模式基于简单工厂模式又对工厂进行了一层抽象,将工厂类也以工厂的形式创建。


五、Spring实现工厂



Spring容器管理一个接口的多个实现类Bean时,可以使用 Map 形式注入所有实现类的Bean,这个Map的Key为注册Bean的BeanName,Map的Value为对应的Bean。所以我们可以利用这个特性使用Spring的IoC功能实现一个工厂模式,还是使用前面的示例。

Spring 默认注册的 BeanName 一般为类名的小驼峰形式,也可以自己指定。

定义一个 Shape 接口,并添加实现类,此时所有的实现类交给Spring管理,编写代码如下:

// Shape.java
public interface Shape {
    void draw();
}
// Circle.java
@Service
public class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("Circle.draw");
    }
}
// Rectangle.java
@Service
public class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("Rectangle.draw");
    }
}
// Square.java
@Service
public class Square implements Shape {
    @Override
    public void draw() {
        System.out.println("Square.draw");
    }
}




定义一个工厂类,也要交给Spring管理,然后使用 Map 注入需要生产的Bean,编写代码如下:

// ShapeFactory.java
@Service
public class ShapeFactory {
    private static Map<String, Shape> shapeMap;
    public static Shape getShape(String beanName) {
        return shapeMap.get(beanName);
    }
    @Autowired
    public void setShapeMap(Map<String, Shape> shapeMap) {
        ShapeFactory.shapeMap = shapeMap;
    }
}

编写主方法类,定义ApplicationContext并扫描前面注册Bean所在的包,编写代码如下:

// Main.java
public class Main {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext("com.ajn.spring.factory");
        Shape circle = ShapeFactory.getShape("circle");
        circle.draw();
        Shape rectangle = ShapeFactory.getShape("rectangle");
        rectangle.draw();
        Shape square = ShapeFactory.getShape("square");
        square.draw();
    }
}


目录
相关文章
|
7月前
|
设计模式
设计模式之工厂 Factory
设计模式之工厂 Factory
57 1
|
7月前
|
设计模式
设计模式(二)工厂方法模式(Factory Method)
设计模式(二)工厂方法模式(Factory Method)
37 0
|
设计模式 Java
设计模式学习(七):Factory Method工厂模式
在Template Method模式中,我们在父类中规定处理的流程,在子类中实现具体的处理。如果我们将该模式用于生成实例,它就演变为本章中我们所要学习的Factory Method模式。
124 0
设计模式学习(七):Factory Method工厂模式
|
存储 设计模式 Java
创建型模式 - 工厂模式(Factory Pattern)
创建型模式 - 工厂模式(Factory Pattern)
|
设计模式
《一天一个设计模式》----工厂方法模式(Factory Method)
《一天一个设计模式》----工厂方法模式(Factory Method)
102 0
《一天一个设计模式》----工厂方法模式(Factory Method)
|
设计模式 缓存 Java
创建型-Factory
一般情况下,工厂模式分为三种更加细分的类型:简单工厂、工厂方法和抽象工厂。不过,在 GoF 的《设计模式》一书中,它将简单工厂模式看作是工厂方法模式的一种特例,所以工厂模式只被分成了工厂方法和抽象工厂两类。实际上,前面一种分类方法更加常见,所以,在今天的讲解中,我们沿用第一种分类方法。
117 0
|
XML 存储 设计模式
JAVA设计模式(01):创建型-工厂模式【工厂方法模式】(Factory Method)
文章为转载:代码为自己写的和改编的。 本节主要代码: https://yunpan.cn/cqa24JbQmyxp7 访问密码 b917 转载自小若博客:http://blog.csdn.net/lovesomnus/article/details/46634987
370 0
JAVA设计模式(01):创建型-工厂模式【工厂方法模式】(Factory Method)
|
Java 设计模式 C++
设计模式:工厂方法模式(Factory Method)和抽象工厂模式(Abstact Factory)
 在面向对象编程中, 最通常的方法是一个new操作符产生一个对象实例,new操作符就是用来构造对象实例的。但是在一些情况下, new操作符直接生成对象会带来一些问题。举例来说, 许多类型对象的创造需要一系列的步骤: 你可能需要计算或取得对象的初始设置; 选择生成哪个子对象实例; 或在生成你需要的对象之前必须先生成一些辅助功能的对象。
6355 1
|
设计模式
设计模式二: 工厂方法(Factory Method)
简介 工厂方法模式是创建型模式的一种, 核心结构有四个角色: 抽象工厂,具体工厂,抽象产品,具体产品; 实现层面上,该模式定义一个创建产品的接口,将实际创建工作推迟到具体工厂类实现, 一个产品对应一个工厂, 这样的好处是当有新产品引入时可以不修改具体的工厂角色. 意图 定义了一个创建对象的接口,但由子类决定要实例化哪个类。
887 0
|
设计模式
工厂模式(Factory)
1、简单工厂 2、工厂方法 3、抽象工厂 简单工厂和工厂方法这俩个设计模式不做详细介绍,请各位看官自行百度,有大量的解释。再次我简单引用一下其他博客主对这三种模式的理解。
1025 0