定义及应用场景
工厂模式是我们最常使用实例化对象模式了,使用工厂方法代替new操作的一种模式。应用场景如下:
- new一个对象时需要很多繁琐的过程,set属性等
- 循环体中创建大量的对象
三种工厂模式
简单工厂模式
简单工厂模式(Simple Factory Pattern)是指由一个工厂对象决定创建出哪一种产品对象实例,又叫做静态工厂方法模式,属于创建型模式,但不属于23种GOF设计模式之一。适用场景:工厂类负责创建的对象较少的场景,客户只知道传入工厂类的参数,对于如何创建对象的逻辑并不需要关心。
//标准接口,产品的抽象
public interface ICourse {
/**
* 直播
*/
void live();
}
//创建一个语文课程的实现类
public class ChineseCourse implements ICourse{
@Override
public void live() {
System.out.println("语文课直播");
}
}
//创建一个数学课程的实现类
public class MathCourse implements ICourse{
@Override
public void live() {
System.out.println("数学课直播");
}
}
//创建简单工厂类
public class CourseSimpleFactory {
public ICourse create(String name) {
if ("math".equalsIgnoreCase(name)) {
return new MathCourse();
} else if ("Chinese".equalsIgnoreCase(name)) {
return new ChineseCourse();
} else {
return new ChineseCourse();
}
}
}
//客户端测试方法
public class SimpleTest {
public static void main(String[] args) {
CourseSimpleFactory factory = new CourseSimpleFactory();
ICourse course = factory.create("math");
course.live();
}
}
//输出:
输出:
数学课直播
缺点:如果我们要增加英语课,那么工厂类中的create()方法就需要根据产品的新增进行代码逻辑的修改。故可用反射:
public class CourseSimpleFactoryUpdate {
public ICourse create(Class<? extends ICourse> clazz) t {
try {
if (clazz != null) {
return clazz.newInstance();
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
//测试方法
public class SimpleTest {
public static void main(String[] args) {
// CourseSimpleFactory factory = new CourseSimpleFactory();
// ICourse course = factory.create("math");
// course.live();
CourseSimpleFactoryUpdate factoryUpdate = new CourseSimpleFactoryUpdate();
ICourse course1 = factoryUpdate.create(MathCourse.class);
course1.live();
}
}
简单工厂的缺点:不易于扩展复杂的产品结构。
工厂方法模式
工厂方法模式是指定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法让类的实例化延迟到子类中进行。在工厂方法模式中用户只需要关心所需产品对应的工厂,无需关心细节,符合开闭原则。
//抽象接口
public interface ICourseFactory {
ICourse create();
}
public class MathFactory implements ICourseFactory{
@Override
public ICourse create() {
return new MathCourse();
}
}
public class ChineseFactory implements ICourseFactory{
@Override
public ICourse create() {
return new ChineseCourse();
}
}
public class MethodTest {
public static void main(String[] args) {
MathFactory mathFactory = new MathFactory();
ICourse course = mathFactory.create();
course.live();
ChineseFactory chineseFactory = new ChineseFactory();
course = chineseFactory.create();
course.live();
}
}
工厂方法模式适用的场景:
- 应用层不依赖于产品类实例如何被创建的细节。
- 一个类通过其子类来指定创建哪个对象。
工厂方法的缺点:类的数量过多,一个产品有对应的产品工厂。增加了系统的复杂度。
抽象工厂模式
抽象工厂模式是指提供一个创建一系列相关的对象的接口,无须指定它们的具体的类。
工厂方法模式:针对的是一个产品等级结构;对应的是一个抽象产品类。
抽象工厂模式:针对的是面向多个产品等级结构;对应的是多个抽象产品类。
上述的课程直播中,对应的甚至上课还需要一些课堂笔记才能构成完整的课程,在产品中增加一个课堂笔记产品。
//2个抽象接口
public interface INote {
void record();
}
public interface ICourse {
void live();
}
//抽象工厂
public interface CourseFactory {
ICourse createLive();
INote createNote();
}
创建语文产品族
public class ChineseNote implements INote {
@Override
public void record() {
System.out.println("语文笔记");
}
}
public class ChineseCourse implements ICourse{
@Override
public void live() {
System.out.println("语文课直播");
}
}
创建数学产品族
public class MathNote implements INote{
@Override
public void record() {
System.out.println("数学笔记");
}
}
public class MathCourse implements ICourse{
@Override
public void live() {
System.out.println("数学课直播");
}
}
//具体的语文工厂
public class ChineseFactory implements CourseFactory{
@Override
public ICourse createLive() {
return new ChineseCourse();
}
@Override
public INote createNote() {
return new ChineseNote();
}
}
//具体的数学工厂
public class MathFactory implements CourseFactory{
@Override
public ICourse createLive() {
return new MathCourse();
}
@Override
public INote createNote() {
return new MathNote();
}
}
public class Test {
public static void main(String[] args) {
ChineseFactory chineseFactory = new ChineseFactory();
chineseFactory.createLive().live();
chineseFactory.createNote().record();
}
}
引用的网图
优点:适用于工厂方法无法满足的场景,例如:生活中的美的,格力就是一个工厂(产品族),对应的空调、冰箱是他们的产品,这些每个工厂生产的产品的等级会有所不同。
缺点:若产品族想扩展新的产品会有所困难,要修改抽象工厂。例如突然想生产净化器。增加了系统的复杂度