定义:
从设计模式的类型上来说,简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。
其中我们应该注意定义中的一句话 "由一个工厂对象决定创建出哪一类产品实例“
【简单工厂设计模式】
工厂模式就是专门负责将大量有共同接口的类实例化,而且不必事先知道每次是要实例化哪一个类的模式。它定义一个用于创建对象的接口,由子类决定实例化哪一个类。
类图:
以上类图引自百度
通过以上类图我们不难发现简单工厂模式总共有三个组件,工厂类(Creator)、产品接口(Iproduct)、具体产品(Pa和Pb)。
这样的结构我们可以发现,工厂类只有一个,那么就意味着所有的产品都由此工厂创建,所以为了使工厂类能够知道我们需要哪一种产品,我们需要在创建产品时传递给工厂类一个参数,去表明我们想要创建哪种产品。
代码实现:
定义一个产品接口
public interface class IProduct {
public void action();
}
定义一个产品类(car)
public class Car implements IProduct {
public void action(){
System.out.println("汽车在路上跑!");
}
}
定义一个产品类(airplane)
public class Airplane implements IProduct {
public void action(){
System.out.println("飞机在天上飞!");
}
}
定义一个创建产品的工厂类(所有的产品都从此创建)
public class Factory {
private Factory(){}
public static IProduct creatProduct(String type){
if("Car".equals(type)){
return new Car();
}else if("Airplane".equals(type)){
return new Airplane();
}else{
return null;
}
}
}
测试类
public class App {
public static void main(String[] args) {
IProduct Car= Factory.createProduct("Car");
car.action();
IProduct airplane = Factory.createProduct("Airplane");
airplane .action();
}
}
注解:
1、所有产品都实现一个产品接口,按照特性重写方法
2、所有产品由工厂类直接创建(所以,工厂在创建时要知道你叫我创建什么产品,即工厂的创建方法需要调用者传一个产品type的参数)
缺点:
每当需要增加新产品创建的时候,都要改变工厂类,不利于维护
实际案例:
还记得我们在学完servlet后做的第一个登陆注册系统吗?一个servlet实现一个功能,这里就不细讲了,直接用我们最简单的工厂模式去改造它!
#1 首先我们必须要一个servlet接口(类似于产品接口一样,而这里具体的servlet则是具体产品)
interface Servlet{}
#2 相当于简单工厂模式中的抽象父类产品。
//注意,简单工厂在网络上的资料大部分为了简单容易理解都是只规划了一个产品接口,但这不代表就只能有一个,设计模式的使用要灵活多变。
class HttpServlet implements Servlet{}
#3 具体的产品
class LoginServlet extends HttpServlet{}
class RegisterServlet extends HttpServlet{}
class LoginoutServlet extends HttpServlet{}
#4 产品工厂
public class ServletFactory {
private ServletFactory(){}
//典型的创造产品的方法,一般是静态的,因为工厂不需要有状态。
public static Servlet createServlet(String servletName){
if (servletName.equals("login")) {
return new LoginServlet();
}else if (servletName.equals("register")) {
return new RegisterServlet();
}else if (servletName.equals("loginout")) {
return new LoginoutServlet();
}else {
throw new RuntimeException();
}
}
}
以上就是我们最初在web服务中用的简单工厂模式
总结:
工厂类负责创建的对象比较少;
客户只知道传入工厂类的参数(如上例子传参浏览器类型),对于如何创建对象(逻辑)不关心;
由于简单工厂很容易违反高内聚责任分配原则,因此一般只在很简单的情况下应用。