简单工厂模式

[TOC]

简单工厂模式的动机

简单工厂模式主要应用在简历大量功能相似的类时。比如在界面上,按钮需要具有相同的画风、外观等等,但是具体的功能不一样。也就是类型相似,但是功能不同(也就是通常拥有相同的父类)。如果使用普通的new对象来创建,将会出现大量的new对象。通常使用一个工厂类来进行创建具体的类。

模式定义

简单工厂模式(Simple Factory Pattern):又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类

模式的结构

简单工厂的角色

工厂模式的 UML 图

代码分析

Shape.java

public interface Shape {
    void draw();
}


Circle.Java
public class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("i am a circle");
    }
}

Square.java
public class Square implements Shape {
    @Override
    public void draw() {
        System.out.println("I am a Square");
    }
}

ShapeFactory.java
public class ShapeFactory {
    public static Shape create(String shapeType){
        if (shapeType == "square"){
            return  new Square();
        } else{
            return new Circle();
        }
    }
    public static void main(String[] args) {
        Shape shape = ShapeFactory.create("square");
        shape.draw();
    }
}

简单工厂模式的意义

  • 简单工厂模式的本质仍然是根据传入的值创建对象,通过不断的if或者else if来判断需要创建的对象
  • 简单工厂模式最大的问题在于工厂类的职责相对过重,增加新的产品需要修改工厂类的判断逻辑,这一点与开闭原则是相违背的。
  • 简单工厂模式的要点在于:当你需要什么,只需要传入一个正确的参数,就可以获取你所需要的对象,而无须知道其创建细节。
  • 简单工厂将同一接口下的类进行统一创建,将创建与使用进行解耦,降低了组件之间的依赖性,对象的业务不依赖于他的对象而是依赖于工厂和统一的接口,工厂基于不同的对象进行调度,如果需要返回别的对象,可以只需要修改工厂类,而不需要找到所有的业务实现中的调用,使对象的创建更加灵活

简单工厂的使用情景

  • 首先因为简单工厂需要不停的进行判断,所以如果需要创建的类太多,工厂方法就会进行复杂的逻辑判断或者长时间的进行匹配,程序运行效率较低
  • 需要对调用方隐藏创建方式

JDK中的应用实例

  • dateformat中使用了工厂方式进行创建

    Dateformat
    
    private static DateFormat get(int timeStyle, int dateStyle,
                                 int flags, Locale loc) {
       if ((flags & 1) != 0) {
           if (timeStyle < 0 || timeStyle > 3) {
               throw new IllegalArgumentException("Illegal time style " + timeStyle);
           }
       } else {
           timeStyle = -1;
       }
       if ((flags & 2) != 0) {
           if (dateStyle < 0 || dateStyle > 3) {
               throw new IllegalArgumentException("Illegal date style " + dateStyle);
           }
       } else {
           dateStyle = -1;
       }
    
       LocaleProviderAdapter adapter = LocaleProviderAdapter.getAdapter(DateFormatProvider.class, loc);
       DateFormat dateFormat = get(adapter, timeStyle, dateStyle, loc);
       if (dateFormat == null) {
           dateFormat = get(LocaleProviderAdapter.forJRE(), timeStyle, dateStyle, loc);
       }
       return dateFormat;
       }
上一篇
下一篇