工厂模式
工厂模式是随着应用的发展衍生出来一种编程习惯,用于创建复杂的对象,或者避免编写大量的重复代码的一种解决方案。
简单工厂
基础工作:
public interface Subject {
void study();
}
public class Java implements Subject {
@Override
public void study() {
System.out.println("学习Java");
}
}
public class Python implements Subject{
@Override
public void study(){
System.out.println("学习Python");
}
}
工厂逻辑:
public class SubjectFactory {
public Subject create(Class<?> clazz) {
if (clazz != null) {
try {
return (Subject) clazz.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
} else {
return null;
}
return null;
}
}
使用方法:
public class SimpleTest {
public static void main(String[] args) throws InstantiationException, IllegalAccessException {
SubjectFactory factory = new SubjectFactory();
factory.create(Java.class).study();
factory.create(Python.class).study();
}
}
学习Java
学习Python
案例中,创建StudyJava和StudyPython的创建逻辑相对简单,因此看起来还不如直接new,但是在实际业务中,对于StudyJava需要添加许多属性,如果有20几个属性需要set,不适用工厂,则每个需要使用该对象的地方都要写二十几个set。
就目前看来,简单工厂的任务时比较复杂的,一个工厂既要负责创建StudyJava实例,也要创建StudyPython实例,是不符合单一职责原则的,而且如果需要单独维护Java,则Python的代码也会被相应地改变。那么有没有一种方法可以使得将两种创建逻辑进行分离呢?
工厂方法
将工厂进行抽象,让不同科目实现自己的实例创建:
public interface SubjectFactory {
Subject creat();
}
public class PythonFactory implements SubjectFactory {
@Override
public Subject creat() {
return new Python();
}
}
public class JavaFactory implements SubjectFactory {
@Override
public Subject creat() {
return new Java();
}
}
测试:
public static void main(String[] args) {
new JavaFactory().creat().study();
new PythonFactory().creat().study();
}
学习Java
学习Python
将不同科目的创建逻辑进行分离,实现单一职责和解耦,更有利于单个科目的维护,但是带来的副作用就是会增加类的个数,给项目启动增加压力,同时代码的理解难度也会有相应的增加。
抽象工厂
但是实际的生产中,产品还会存在着多个维度的属性,我们称为产品簇。
public interface Note {
void edit();
}
public interface Video {
void watch();
}
public class JavaNote implements Note {
@Override
public void edit() {
System.out.println("编写Java笔记");
}
}
public class JavaVideo implements Video {
@Override
public void watch() {
System.out.println("观看Java视频");
}
}
public class PythonNote implements Note {
@Override
public void edit() {
System.out.println("编写Python笔记");
}
}
public class PythonVideo implements Video {
@Override
public void watch() {
System.out.println("观看Python视频");
}
}
将一个产品簇归结到一个工厂
public interface SubjectFactory {
Note edit();
Video watch();
}
针对不同产品进行不同的实现
public class JavaFactory implements SubjectFactory {
@Override
public Note edit() {
return new JavaNote();
}
@Override
public Video watch() {
return new JavaVideo();
}
}
public class PythonFactory implements SubjectFactory {
@Override
public Note edit() {
return new PythonNote();
}
@Override
public Video watch() {
return new PythonVideo();
}
}
测试
public static void main(String[] args) {
JavaFactory javaFactory = new JavaFactory();
javaFactory.edit().edit();
javaFactory.watch().watch();
PythonFactory pythonFactory = new PythonFactory();
pythonFactory.edit().edit();
pythonFactory.watch().watch();
}
编写Java笔记
观看Java视频
编写Python笔记
观看Python视频
抽象工厂更贴近实际产品,而且拥有较强的扩展性,如果需要对科目进行扩展,增加一个C++,只需要增加C++的工厂和相应的笔记和视频,可以在已上线的情况下,不修改原来的产品的基础上进行增加科目。