简单工厂模式
简单工厂模式(Simple Factory Pattern)是指由一个工厂对象决定创建出哪一种产品类 的实例,但它不属于 GOF,23 种设计模式(参考资料: http://en.wikipedia.org/wiki/Design_Patterns#Patterns_by_Type)。简单工厂适用 于工厂类负责创建的对象较少的场景,且客户端只需要传入工厂类的参数,对于如何创 建对象的逻辑不需要关心。
public interface ICourse {
public void record();
}
public class JavaCourse implements ICourse {
@Override
public void record() {
System.out.println("java 课程");
}
}
public static void main(String[] args) {
ICourse course = new JavaCourse();//如果有其它課程会new 很多不同的课程
//如:new PythonCourse(),new GoCourse() ...等
course.record();
}
可以看到如果有其他课程 会new很多不同的课程,客户端会比较臃肿,用简单工厂优化:
先创建一个工厂类
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 static void main(String[] args) {
//ICourse course = new JavaCourse();//如果有其它課程会new 很多不同的课程
//如:new PythonCourse(),new GoCourse() ...等
//course.record();
CourseFactory courseFactory = new CourseFactory();
ICourse iCourse = courseFactory.create("python");
iCourse.record();
}
可以看到创建工厂时,每次增加课程都需要改代码 ,不符合开闭原则,可以优化:
public ICourse create1(Class<? extends ICourse> clazz){
if(clazz == null){
return null;
}
try {
return (ICourse)clazz.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
测试
public static void main(String[] args) {
//ICourse course = new JavaCourse();//如果有其它課程会new 很多不同的课程
//如:new PythonCourse(),new GoCourse() ...等
//course.record();
// CourseFactory courseFactory = new CourseFactory();
// ICourse iCourse = courseFactory.create("python");
// iCourse.record();
//优化1
CourseFactory courseFactory = new CourseFactory();
ICourse iCourse = courseFactory.create1(PythonCourse.class);
iCourse.record();
}
工厂(方法)模式
- 工厂方法模式(Fatory Method Pattern)是指定义一个创建对象的接口,但让实现这个 接口的类来决定实例化哪个类,工厂方法让类的实例化推迟到子类中进行。在工厂方法 模式中用户只需要关心所需产品对应的工厂,无须关心创建细节,而且加入新的产品符 合开闭原则
- 根据单一职责原则我们将职能继续拆分,专人干专事。Java 课程由 Java 工厂创建, Python 课程由 Python 工厂创建,对工厂本身也做一个抽象(
相当于在简单工厂的基础上包多一层
),有新的产品加入只需要增加这个产品的类 和对应的工厂不需要改已有代码。来看代码
,先创建 ICourseFactory 接口:
public interface ICourseFactory {
ICourse create();
}
对应每种产品的工厂:
public class JavaCourseFacotry implements ICourseFactory {
@Override
public ICourse create() {
return new JavaCourse();
}
}
// 或
public class PythonCourseFactory implements ICourseFactory {
@Override
public ICourse create() {
return new PythonCourse();
}
}
测试
public class TestClass {
public static void main(String[] args) {
ICourseFactory factory = new JavaCourseFacotry();
ICourse course = factory.create();
course.record();
}
}
工厂方法缺点
- 类的个数容易过多,增加复杂度。
- 增加了系统的抽象性和理解难度。
抽象工厂模式
- 当生成产品非常复杂时可以用抽象工厂(在我看来类似再继承多一层)
- 将一个系列的产品族统一到一起创建
//要求所有的子工厂都实现这个工厂
public interface ICourseFactory {
ICourse createCurse();
INote createNote();
IVideo createVideo();
}
//除课程外增加笔记 和视频
public interface INote {
public void note();
}
public interface IVideo {
public void video();
}
public class JavaCourseFactory implements ICourseFactory{
@Override
public ICourse createCurse() {
return new JavaCourse();
}
@Override
public INote createNote() {
return new JavaNote();
}
@Override
public IVideo createVideo() {
return new JavaVideo();
}
}
测试类
public class AbstractFactoryTest {
public static void main(String[] args) {
ICourseFactory factory = new JavaCourseFactory();
factory.createCurse().record();
factory.createNote().note();
}
}
抽象工厂缺点:
- 不符合开闭原则
- 规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂 的接口(如:如果我添加一个ISource接口,那么所有工厂都需要增加这个接口)
- 增加了系统的抽象性和理解难度