简单工厂模式

2016/08/18 设计模式

定义

简单工厂模式(Simple Factory Pattern)属于类的创新型模式,又叫静态工厂方法模式(Static FactoryMethod Pattern),是通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

类图

简单工厂类图 从上图可以看出总共有三种类,一个产品工厂ProductFactory;一个产品接口Product;一个具体产品,如ConcreteProduct2和ConcreteProduct1;工厂类负责产品生产逻辑,通过我们传入的参数确定最终得到的产品,用户不关系产品创造的细节;

java代码实现

产品接口

public interface Product {
    void method();
}

产品实现

public class ConcreteProduct1 implements Product {
    @Override
    public void method() {
        System.out.println("产品1方法");
    }
}

需要增加产品就继续实现Product接口进行实现就行了

产品工厂

public class ProductFactory {

    public static Product getProduct(String productName) throws Exception {
        switch (productName) {
            case "product1":
                return new ConcreteProduct1();
            case "product2":
                return new ConcreteProduct2();
            default:
                throw new Exception("本工厂没有其他的产品");
        }
    }
}

以上便是类图转为java代码的简单例子,为了更方便理解,下面我们给出实际中的例子去更好的阐述简单工厂。

实例

模拟action处理,为了更好的体现主题简单工厂模式,我们不关心许多的其他细节。

IAction (产品接口)

public interface IAction {
    void execute();
}

具体的action实现 (产品实现)

public class LoginActon implements IAction {
    @Override
    public void execute() {
        System.out.println("这里写登陆逻辑");
    }
}

public class RegisterActon implements IAction {
    @Override
    public void execute() {
        System.out.println("这里写注册逻辑");
    }
}

创建action的工厂 (产品工厂)

public class ActionFactory {
    public static IAction createAction(String actionName) throws Exception {
        if (actionName.equalsIgnoreCase("login")) {
            return new LoginActon();
        } else if (actionName.equalsIgnoreCase("register")) {
            return new RegisterActon();
        } else {
            throw new Exception("没有其他action");
        }
    }
}

Servlet接口

/**
 * web.xml 配置:
 * <servlet>
 * <servlet-name>route</servlet-name>
 * <servlet-class>RouteServlet</servlet-class>
 * </servlet>
 * <servlet-mapping>
 * <servlet-name>route</servlet-name>
 * <url-pattern>/route/*</url-pattern>
 * </servlet-mapping>
 */
public class RouteServlet extends HttpServlet {
    private static final String PREFIX = "route/";

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String uri = req.getRequestURI();
        Matcher matcher = Pattern.compile("(?<=" + PREFIX + ").*").matcher(uri);
        String actionStr = "register";
        if (matcher.find()) {
            actionStr = matcher.group();
        }
        try {
            IAction action = ActionFactory.createAction(actionStr);
            action.execute();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

如果我们以后需要增加一项业务,比如获取用户列表那么我们就新增一个实现了IAction接口的UserAction,当然简单工厂下我们必须改变ActionFactory的逻辑判断代码。但是简单工厂也为我们带来了好处,我们不用再书写web.xml配置,请求可以被自动路由的对应的action。

总结

设计原则:遵循单一职责、违背开闭原则
常用场景:需要在一堆产品中选择其中一个产品
使用概率:99.99999%
复杂度:低
变化点:产品的种类
选择关键点:一种产品是否可根据某个参数决定它的种类
逆鳞:工厂类不能正常工作
相关设计模式
工厂方法模式:工厂方法模式是简单工厂模式的进一步抽象化,在这两者之间做选择,主要看将工厂进一步抽象化是否有必要,通常情况下,如果工厂的作用仅仅是用来制造产品,则没必要使用工厂方法模式。

Search

    Post Directory