一、 简单工厂(Simple Factory Pattern)
1、概念
一个工厂对象决定创建出哪一种产品类的实力,但不属于GOF23种设计模式。
简单工厂适用于工厂类负责创建的对象较少的场景,且客户端只需要传入工厂类的参数,对于如何创建对象的逻辑不需要关心。
2、实例
1)简单定义
public interface ICourse {
/**
* 录制视频
* @return
*/
public void record();
}
public class JavaCourse implements ICourse {
public void record() {
System.out.println("录制Java课程");
}
}
public class PythonCourse implements ICourse {
public void record() {
System.out.println("录制Python课程");
}
}
public class SimpleFactoryTest {
public static void main(String[] args) {
ICourse iCourse = new JavaCourse();
iCourse .create("java");
}
}
客户端也就是测试类中,依赖JavaCourse,如果业务拓展,需要增加更多的Course类型,那么客户端的依赖会变得臃肿。
2)优化1
基于上述,建议一个工厂类
public class CourseFactory {
public 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) {
//优化一
CourseFactory courseFactory = new CourseFactory();
courseFactory.create("java");
}
}
客户端的调用简单了,但是如果业务继续拓展 ,工厂中的create()就要修改代码逻辑,不符合开闭原则。还可以继续优化。
3)优化二
利用反射
public class CourseFactory {
public ICourse create(String className) {
try {
if (!(null == className || "".equals(className))) {
return (ICourse) Class.forName(className).newInstance();
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public ICourse create(Class<? extends ICourse> clazz){
try {
if (null != clazz) {
return clazz.newInstance();
}
}catch (Exception e){
e.printStackTrace();
}
return null;
}
}
public class SimpleFactoryTest {
public static void main(String[] args) {
CourseFactory courseFactory = new CourseFactory();
ICourse iCourse = courseFactory.create("com.SimpleFactoryPattern.SimpleTwo.JavaCourse");
iCourse.record();
CourseFactory courseFactory1 = new CourseFactory();
ICourse iCourse1 = courseFactory1.create(JavaCourse.class);
iCourse.record();
}
}
产品的添加不再需要修改CourseFactory
3、案例
例如在Calendar类中
Calendar.getInstance()
缺点:
工厂类的职责相对过重,不易于扩展过于复杂的产品结构
二、工厂方法模式
1.概念
定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方法让类的实例化推迟到子类中。在工厂方法模式中用户只需要关心所需产品对应的工厂,无需关心创建细节。
2、实例
基于上面实例
public interface ICourseFactory {
ICourse create();
}
public class JavaCourseFactory implements ICourseFactory {
public ICourse create() {
return new JavaCourse();
}
}
public class PythonCourseFactory implements ICourseFactory {
public ICourse create() {
return new PythonCourse();
}
}
public class FactoryMethodTest {
public static void main(String[] args) {
ICourseFactory factory = new PythonCourseFactory();
ICourse course = factory.create();
course.record();
factory = new JavaCourseFactory();
course = factory.create();
course.record();
}
}
适用场景:
- 创建对象需要大量重复的代码
- 客户端不依赖于产品类实例如何被创建、实现等细节
- 一个类通过其子类来指定创建哪个对象
缺点:
- 类的个数过多,增加复杂度
- 增加系统的抽象性和理解难度
3、抽象工厂模式(Abastract Factory Pattern)
1、概念
提供一个创建一系列相关或者相互依赖对象的接口,无需指定具体的类。客户端不依赖于产品类实例如何被创建、实现等细节。强调的是一系列相关的产品对象(同一产品族)一起使用创建对象需要大量重复的代码,提供一个产品类的库,所有的产品以同样的接口出现,从而客户端不依赖于具体实现。
2、实例
public interface ICourse {
/**
* 录制视频
* @return
*/
void record();
}
public interface INote {
void edit();
}
public interface IVideo {
void record();
}
public class JavaCourse implements ICourse {
public void record() {
System.out.println("录制Java课程");
}
}
public class JavaNote implements INote {
public void edit() {
System.out.println("编写Java笔记");
}
}
public class JavaVideo implements IVideo {
public void record() {
System.out.println("录制Java视频");
}
}
同理可以创建其他课程,实现接口
public abstract class CourseFactory {
public void init(){
System.out.println("初始化基础数据");
}
protected abstract INote createNote();
protected abstract IVideo createVideo();
}
public class JavaCourseFactory extends CourseFactory {
public INote createNote() {
super.init();
return new JavaNote();
}
public IVideo createVideo() {
super.init();
return new JavaVideo();
}
}
public class AbstractFactoryTest {
public static void main(String[] args) {
JavaCourseFactory factory = new JavaCourseFactory();
factory.createNote().edit();
factory.createVideo().record();
}
}
例如就是Java作为一个产品族,Python作为一个产品族等等。如果继续拓展产品等级,比如创建代码createCode(),就需要从抽象工厂到具体工厂都需要调整,不符合开闭原则。
缺点:
- 规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂的接口
- 增加系统的抽象性和理解难度