我就问你,会不会工厂模式?(上)

简介: 简单工厂模式(Simple Factory Pattern)是指由一个工厂对象决定创建出哪一种产品类的实例。简单工厂适用于工厂类负责创建的对象较少的场景,且客户端只需要传入工厂类的参数,对于如何创建对象的逻辑不需要关心。

简单工厂

简单工厂模式(Simple Factory Pattern)是指由一个工厂对象决定创建出哪一种产品类的实例。简单工厂适用于工厂类负责创建的对象较少的场景,且客户端只需要传入工厂类的参数,对于如何创建对象的逻辑不需要关心。

接下来我们来看代码,还是以课程为例。我们定义一个课程标准 ICourse 接口:

public interface ICourse {
    //录制视频
    void record();
}

创建一个 Java 课程的实现 JavaCourse 类:

public class JavaCourse implements ICourse {
    @Override
    public void record() {
        System.out.println("录制java视频");
    }
}

看客户端调用代码,一般我们会这样写:

public class SimpleFactoryTest {
    public static void main(String[] args) {
        ICourse course = new JavaCourse();
        course.record();
    }
}

看上面的代码,父类 ICourse 指向子类 JavaCourse 的引用,应用层代码需要依赖JavaCourse,如果业务扩展,我继续增加 PythonCourse 甚至更多,那么我们客户端的依赖会变得越来越臃肿。因此,我们要想办法把这种依赖减弱,把创建细节隐藏。虽然目前的代码中,我们创建对象的过程并不复杂,但从代码设计角度来讲不易于扩展。现在,我们用简单工厂模式对代码进行优化。先增加课程 PythonCourse 类:

public class PythonCourse implements ICourse {
    @Override
    public void record() {
        System.out.println("录制Python视频");
    }
}

创建 CourseFactory 工厂类:

public class CourseFactory {
    public static ICourse create(String name){
        if("java".equals(name)){
            return new JavaCourse();
        }else if("python".equals(name)){
            return new PythonCourse();
        }else {
            return null;
        }
    }
}

修改测试代码:

public class SimpleFactoryTest {
    public static void main(String[] args) {
        //ICourse course = new JavaCourse();
        ICourse course = CourseFactory.create("java");
        course.record();
    }
}

现在客户端调用是不是就简单了呢,但如果我们业务继续扩展,要增加前端课程,那么工厂中的 create()就要根据产品的增加每次都要修改代码逻辑。不符合开闭原则。因此,我们对简单工厂还可以继续优化,可以采用反射技术:

public class CourseFactory {
    public static ICourse create(String className){
        //这里没有引入springUtil相关的jar包,也没有自己封装,将就吧
        if(className != null && !"".equals(className)){
            try {
                return (ICourse) Class.forName(className).newInstance();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}

修改测试代码:

public class SimpleFactoryTest {
    public static void main(String[] args) {
        //ICourse course = new JavaCourse();
        //ICourse course = CourseFactory.create("java");
        ICourse course = CourseFactory.create("com.cl.factory.simplefactory.JavaCourse");
        course.record();
    }
}

优化之后,产品不断丰富不需要修改 CourseFactory 中的代码。但是,有个问题是,方法参数是字符串,可控性有待提升,而且还需要强制转型。我们再修改一下代码:

public class CourseFactory {
    public static ICourse create(Class<? extends ICourse> clazz){
        if(clazz != null){
            try {
                return clazz.newInstance();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}

优化测试代码:

public class SimpleFactoryTest {
    public static void main(String[] args) {
        //ICourse course = new JavaCourse();
        //ICourse course = CourseFactory.create("java");
        //ICourse course = CourseFactory.create("com.cl.factory.simplefactory.JavaCourse");
        ICourse course = CourseFactory.create(JavaCourse.class);
        course.record();
    }
}
相关文章
|
2月前
|
设计模式 Java
实现一个工厂模式
实现一个工厂模式
34 0
|
2月前
|
设计模式 调度
重看工厂模式
重看工厂模式
22 0
|
12天前
|
设计模式
创建型模式之工厂模式
创建型模式之工厂模式
|
2月前
工厂模式
工厂模式
30 0
|
2月前
|
设计模式 Java
详细讲解什么是工厂模式
详细讲解什么是工厂模式
|
2月前
|
设计模式 C++
【C++】—— 工厂模式详解
【C++】—— 工厂模式详解
工厂模式——学雷锋做好事
工厂模式——学雷锋做好事
|
11月前
|
前端开发
复杂工厂模式
复杂工厂模式
56 1
|
10月前
|
存储 设计模式 Java
多种工厂模式的运用
多种工厂模式的运用
30 0
|
12月前
|
C++
【C++提高】 工厂模式
【C++提高】 工厂模式
42 0