什么是工厂模式?
工厂模式是Java中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式
在工厂模式中,创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象
意图
使用工厂模式的意图:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行
工厂模式的优缺点
优点:
- 一个调用者想创建一个对象的时候,只要知道它的名称就可以了
- 扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以了
- 屏蔽产品的具体实现,调用者只要关心产品的接口就可以了
缺点:
- 每次增加一个产品时,都需要正价一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖
使用工厂模式需要注意什么?
作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂模式。但是有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,比如只需要通过 new 就可以完成创建对象的,这种无需使用工厂模式。如果使用了工厂模式,就需要引入一个工厂类,会增加系统的复杂度
简单工厂模式
具体代码实现
比如每个大学都会有个选课系统,定义一个接口(或者抽象类都行),下面这是一个选课的接口
public interface Course{
//描述每个课程
void selectCourse();
}
先搞个课程,既然要选课肯定得有多个选择嘛对吧
public class JavaCourse implements Course{ //实现Course接口
@Override
public void selectCourse() { //实现接口中的方法
System.out.println("我选了Java程序设计");
}
}
一个课程应该还不够,再来一个
public class PythonCourse implements Course{ //实现Course接口
@Override
public void selectCourse() { //实现接口中的方法
System.out.println("我选了Python编程");
}
}
再来一个
public class GoCourse implements Course{ //实现Course接口
@Override
public void selectCourse() { //实现接口中的方法
System.out.println("我选了Go编程");
}
}
OK,课程列表已经弄好了,现在弄个选课系统(简单工厂类),选课系统如下:
public class CourseFactory{
public static final int JAVA_COURSE = 1; //Java程序设计
public static final int PYTHON_COURSE = 2; //Python编程
public static final int GO_COURSE = 3; //Go编程
public static Course createCourse(int courseType){
switch (courseType){
case JAVA_COURSE:
return new JavaCourse();
case PYTHON_COURSE:
return new PythonCourse();
case GO_COURSE:
default:
return new GoCourse();
}
}
}
接下来我们创建一个主函数来测试一下
/**
* 简单工厂模式
*/
public class Test {
public static void main(String[] args) {
CourseFactory courseFactory = new CourseFactory();//创建工厂
Course course = CourseFactory.createCourse(CourseFactory.JAVA_COURSE); //选课
Course course1 = CourseFactory.createCourse(CourseFactory.PYTHON_COURSE);
Course course2 = CourseFactory.createCourse(CourseFactory.GO_COURSE);
course.selectCourse(); //打印选课结果
course1.selectCourse();
course2.selectCourse();
}
}
输出:
我选了Java程序设计
我选了Python编程
我选了Go编程
特点
-
它是一个接口,有一个重要的 selectCourse 方法,利用 if 或者 switch 创建产品并返回
-
selectCourse 方法通过通常的静态的,所以也称为静态工厂
缺点
- 扩展性差(如果我想增加多一门课程的话(类),还需要修改选课系统(工厂类))
- 不同的课程需要不同额外参数的时候不支持
抽象工厂模式
什么是抽象工厂模式?
抽象工厂模式是围绕着一个超级工程创建其它的工厂;该超级工厂又称为其它工厂的工厂(好绕对不对哈哈)。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在抽象工厂模式中
定义
为创建一组相关或相互依赖的对象提供一个接口,而且无需指定它们的具体类,每个生成的工厂都可以按照工厂模式提供对象
实现抽象工厂的关键
在一个工厂里聚合多个同类的产品
具体代码实现
创建一个1号课程接口,如下:
interface CourseOne{
void selectCourse();
}
创建2号课程接口
interface CourseTwo{
void selectCourse();
}
实现1号课程
class Course1 implements CourseOne{
@Override
public void selectCourse() {
System.out.println("选择一号课程");
}
}
实现2号课程
class Course2 implements CourseTwo{
@Override
public void selectCourse() {
System.out.println("选择二号课程");
}
}
定义一个工厂
interface Factory{
CourseOne createCourseOne();
CourseTwo createCourseTwo();
}
实现上面的工厂
class CourseFactory implements Factory{
@Override
public CourseOne createCourseOne() {
return new Course1();
}
@Override
public CourseTwo createCourseTwo() {
return new Course2();
}
}
主函数
使用 CourseFactory来获取 CourseFactory,通过传递类型信息来获取实体类的对象。
public class SynchronizedDemo2 {
public static void main(String[] args) {
//创建工厂
CourseFactory factory = new CourseFactory();
//打印
factory.createCourseOne().selectCourse();
factory.createCourseTwo().selectCourse();
}
}
优点
抽象工厂最重要的优点就是可以在类的内部对产品进行约束,所谓的产品就是或多或少都存在一定的关联,抽象工厂模式就可以在类的内部对产品的关联进行定义和描述,而不必专门引入一个新的类来进行管理
缺点
产品的扩展是一件十分费力的事情,比如需要增加一个新的产品的时候,几乎所有的工厂类都需要进行修改,所以使用抽象工厂模式的时候,最好对产品的结构划分等级
总结
无论是简单的工厂模式还是抽象工厂模式,它们都属于工厂模式,在形式和特点上也是极为相似的,它们最终的目的都是为了解耦,在使用的时候,我们不必去在意这个模式到底是工厂模式还是抽象工厂模式,所以在使用工厂模式的时候,只需关心是否达到了降低耦合的目的