简单工厂
简单工厂模式(Simple Factory Pattern)是指由一个工厂对象决定创建出哪一种产品类的实例。简单工厂适用于工厂类负责创建的对象较少的场景,且客户端只需要传入工厂类的参数,对于如何创建对象的逻辑不需要关心
public interface ICourse { //录制视频 void record(); } --------------------------------------------- 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(); } }
我们要想办法把这种依赖减弱,把创建细节隐藏
public class PythonCourse implements ICourse { @Override public void record() { System.out.println("录制Python视频"); } } -------------------------------------------------- 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(); } } -------------------------------------------------- 利用反射 ss 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(); } } -------------------------------------------------- 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(); } } return null; -------------------------------------------------- 问题是,方法参数是字符串,可控性有待提升,而且还需要强制转型 改 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(); } } -------------------------------------------------- //这个代码应该很熟悉 Logger logger = LoggerFactory.getLogger(CacheManager.class); //看下它的实现 public static Logger getLogger(String name) { ILoggerFactory iLoggerFactory = getILoggerFactory(); return iLoggerFactory.getLogger(name); } public static Logger getLogger(Class<?> clazz) { Logger logger = getLogger(clazz.getName()); if (DETECT_LOGGER_NAME_MISMATCH) { Class<?> autoComputedCallingClass = Util.getCallingClass(); if (autoComputedCallingClass != null && nonMatchingClasses(clazz, autoComputedCallingClass)) { Util.report(String.format("Detected logger name mismatch. Given name: "%s"; computed name: "%s".", logger.getName(), autoComputedCallingClass.getName())); Util.report("See http://www.slf4j.org/codes.html#loggerNameMismatch for an explanation"); } } return logger; }
工厂方法模式
工厂方法模式(Fatory Method Pattern)是指定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方法让类的实例化推迟到子类中进行。在工厂方法模式中用户只需要关心所需产品对应的工厂,无须关心创建细节,而且加入新的产品符合开闭原则。工厂方法模式主要解决产品扩展的问题,在简单工厂中,随着产品链的丰富,如果每个课程的创建逻辑有区别的话,工厂的职责会变得越来越多,有点像万能工厂,并不便于维护。根据单一职责原则我们将职能继续拆分,专人干专事。Java 课程由 Java 工厂创建,Python 课程由 Python 工厂创建,对工厂本身也做一个抽象。来看代码,先创建ICourseFactory 接口:
public interface ICourseFactory { ICourse crete(); } public class JavaCourseFactory implements ICourseFactory { @Override public ICourse crete() { return new JavaCourse(); } } public class PythonCourseFactory implements ICourseFactory { @Override public ICourse crete() { return new PythonCourse(); } } public class SimpleFactoryTest { public static void main(String[] args) { ICourseFactory courseFactory = new JavaCourseFactory(); ICourse course = courseFactory.crete(); course.record(); courseFactory = new PythonCourseFactory(); course = courseFactory.crete(); course.record(); } }
工厂方法适用于以下场景:
-
创建对象需要大量重复的代码。
-
客户端(应用层)不依赖于产品类实例如何被创建、实现等细节。
-
一个类通过其子类来指定创建哪个对象。
工厂方法的缺点
-
类的个数容易过多,增加复杂度。
-
增加了系统的抽象性和理解难度。
抽象工厂模式
抽象工厂模式(Abastract Factory Pattern)是指提供一个创建一系列相关或相互依赖对象的接口,无须指定他们具体的类。客户端(应用层)不依赖于产品类实例如何被创建、实现等细节,强调的是一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量重复的代码。需要提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现。
public interface IVideo { void record(); } -------------------------------- public interface INote { void edit(); } -------------------------------- public class JavaVideo implements IVideo { @Override public void record() { System.out.println("java视频"); } } -------------------------------- public class JavaNote implements INote { @Override public void edit() { System.out.println("java笔记"); } } -------------------------------- public interface CourseFactory { INote createNote(); IVideo createVideo(); } -------------------------------- public class JavaCourseFactory implements CourseFactory { @Override public INote createNote() { return new JavaNote(); } @Override public IVideo createVideo() { return new JavaVideo(); } } -------------------------------- public class PythonVideo implements IVideo { @Override public void record() { System.out.println("python视频"); } } -------------------------------- public class PythonCourseFactory implements CourseFactory { @Override public INote createNote() { return new PythonNote(); } @Override public IVideo createVideo() { return new PythonVideo(); } } -------------------------------- public class AbstractFactoryTest { public static void main(String[] args) { JavaCourseFactory javaCourseFactory = new JavaCourseFactory(); javaCourseFactory.createNote().edit(); javaCourseFactory.createVideo().record(); PythonCourseFactory pythonCourseFactory = new PythonCourseFactory(); pythonCourseFactory.createNote().edit(); pythonCourseFactory.createVideo().record(); } }
-
规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂的接口。
-
增加了系统的抽象性和理解难度。