学习路径:https://coding.imooc.com/class/270.html
【简单工厂】不属于设计模式,是一种【编码风格】
【工厂方法】、【抽象工厂】属于【创建型】的设计模式
1. 简单工厂
好处:减少应用层代码量
// 基础简单工厂
FruitFactory fruitFactory = new FruitFactory();
// 约定一个标识让工厂去生成,这里可以用反射的方式演进得更合理
Fruit fruit = fruitFactory.getFurit("apple");
fruit.produce();
// 使用反射演进的简单工厂
FruitFactory fruitFactory = new FruitFactory();
// 约定一个标识让工厂去生成,这里可以用反射的方式演进得更合理
Fruit fruit = fruitFactory.getFurit(Apple.class);
fruit.produce();
// 反射的相关代码
public Fruit getFruit(Class c) {
Fruit fruit = null;
fruit = (Fruit) Class.forName(c.getName()).newInstance();
return fruit;
}
2. 工厂方法
业务场景:拓展同类产品
好处:当需要增加同类产品时候,只需要新增加一个工厂,再新增一个产品类即可,不用改之前的代码。
// 工厂方法
VideoFactory videoFactory = new JavaVideoFactory();
// 演进为抽象工厂方法的思考 -- 如果需要新增一个PythonVideo的课程怎么办?【重点是解耦】
Video video = videoFactory.getVideo();
video.produce();
思考问题:如果要增加一个Java源码的产品,就需要增加新的CodeFactory标准和Code标准,这样会增加冗余。引入抽象工厂解决这类问题。
3. 抽象工厂
业务场景:同样是拓展同类产品,但是一类产品下有多个属性,比如一个课程有多个属性,分别是视频、手记
好处:完成了课程属性与应用层的解耦。
CourseFactory courseFactory = new JavaCourseFactory();
Video video = courseFactory.getVideo();
Article article = courseFactory.getArticle();
video.produce();
article.produce();
该业务场景下,将属性抽象成标准,每个产品都可以实现属性
如视频和手记设立一个标准,每个课程都有这两个属性,拓展一个新课程时需要新增课程工厂,还有新增对应属性的实现类。
首先要明白【产品等级】和【产品族】的区别
产品等级: 美的空调、格力空调、松下空调 | java课程、python课程、C++课程
产品族:美的空调、美的电饭煲、美的洗衣机 | java视频、java手记、java源码
工厂方法面向 方便拓展【产品等级】
抽象工厂面向 方便拓展【产品族】
1.使用工厂方法,可以优雅地增加产品等级
如已存在【java视频、python视频】,现新增【C++视频】。
public abstract class VideoFactory { // java视频工厂、python视频工厂、C++视频视频工厂,继承videoFactory,设置get方法
public abstract Video getVideo();
}
public abstract class Video { // java视频、python视频、C++视频,继承video, 需要定义不同视频的内容或生产逻辑
public abstract void produce();
}
VideoFactory videoFactory = new JavaVideoFactory();
Video video = videoFactory.getVideo();
video.produce();
public interface CourseFactory {
// 这三个方法放在一起,牺牲了维护成本,提高了复杂业务的实现能力
Video getVideo();
Article getArticle();
Source getSource();
}
public abstract class Article {
public abstract void produce();
}
public abstract class Video {
public abstract void produce();
}
public abstract class Source{
public abstract void produce();
}
工厂方法复杂度较低,处理的业务场景简单。
抽象工厂复杂度较高,处理的业务场景复杂,但是产品族的需求变动会导致代码大量改动。