简单工厂模式

以学习为例,假如你想学习Java视频,你得自己到处去找资料,找资料是一个繁琐的过程,过一段时间你又想学Python视频了,你还得去找资料。现在你在学校上学,你想学Java视频了,你跟老师说,我想学Java视频了,老师就给了你一套Java视频,我想学Python视频了,老师就给了你一套Python视频,是不是感觉很方便,简单工厂模式就是将创建具体类的过程交给工厂类来实现

public abstract class Video {
abstract void study();
}
public class JavaVideo extends Video {
void study() {
System.out.println("学习Java视频");
}
}
public class PythonVideo extends Video {
void study() {
System.out.println("学习Python视频");
}
}
public class VideoFactory {

public static Video getVideo(String type) {
if ("java".equalsIgnoreCase(type)) {
return new JavaVideo();
} else if ("python".equalsIgnoreCase(type)) {
return new PythonVideo();
}
return null;
}
}
public class Test {

public static void main(String[] args) {
Video car = VideoFactory.getVideo("java");
// 学习Java视频
car.study();
}
}

但是这样做是不符合开闭原则的(对于扩展是开放的,对于修改是关闭的),因为每次增加新的课程就得修改if else语句,可以用反射 传入类的对象解决

public class VideoFactory {

public static Video getVideo(Class c) {
Video video = null;
try {
video = (Video) Class.forName(c.getName()).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return video;
}
}

当然还可以用工厂方法模式解决

工厂方法模式

工厂方法模式的实质是定义一个创建对象的接口或抽象类,但让实现这个接口的类来决定实例化哪个类。工厂方法让类的实例化推迟到子类中进行。

在工厂模式中,创建对象的过程在一个工厂类中,不符合开闭原则,工厂模式就解决了这个问题,对上面的例子进行改进,每一门课程都创建一个工厂类,当增加新的课程时,只要实现工厂接口或工厂抽象类创建新的工厂类即可,在这个新的工厂类中实例化新的课程

public abstract class VideoFactory {

public abstract Video getVideo();
}
public class JavaVideoFactory extends VideoFactory {
public Video getVideo() {
return new JavaVideo();
}
}

需要哪个对象,用相应的工厂类创建即可

public class Test {

public static void main(String[] args) {
VideoFactory videoFactory = new JavaVideoFactory();
Video video = videoFactory.getVideo();
// 学习Java视频
video.study();
}
}

抽象工厂模式

在工厂方法模式中具体工厂负责生产具体的产品,每一个具体工厂对应一种具体产品,工厂方法具有唯一性。但是有时候我们希望一个工厂可以提供多个产品对象,而不是单一的产品对象,如一个电器工厂,它可以生产电视机、电冰箱、空调等多种电器,而不是只生产某一种电器。为了更好地理解抽象工厂模式,我们先引入两个概念

工厂模式(简单工厂模式、工厂方法模式、抽象工厂模式)详解_ide

(1) 产品等级结构:产品等级结构即产品的继承结构,如一个抽象类是电冰箱,其子类有海尔电冰箱、长虹电冰箱、则电冰箱与具体品牌的电冰箱之间构成了一个产品等级结构,抽象电冰箱是父类,而具体品牌的电冰箱是其子类。

(2) 产品族:在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品,如海尔电器工厂生产的海尔电视机、海尔电冰箱,海尔电视机位于电视机产品等级结构中,海尔电冰箱位于电冰箱产品等级结构中,海尔电视机、海尔电冰箱构成了一个产品族。

在上面的例子中,假如我们除了想学习Java视频,还想学习Java笔记,如果对每个产品都创建工厂,会造成类爆炸。这时就可以生成一个Java课程抽象工厂,提供Java这个产品族的对象

public abstract class Article {
public abstract void study();
}
public class JavaArticle extends Article {
public void study() {
System.out.println("学习Java笔记");
}
}
public abstract class CourseFactory {

public abstract Video getVideo();
public abstract Article getArticle();
}
public class JavaCourseFactory extends CourseFactory {
public Video getVideo() {
return new JavaVideo();
}

public Article getArticle() {
return new JavaArticle();
}
}
public class Test {

public static void main(String[] args) {
CourseFactory courseFactory = new JavaCourseFactory();
Video video = courseFactory.getVideo();
Article article = courseFactory.getArticle();
// 学习Java视频
video.study();
// 学习Java笔记
article.study();
}
}

抽象工厂模式与工厂方法模式最大的区别在于,工厂方法模式针对的是一个产品等级结构,而抽象工厂模式需要面对多个产品等级结构,一个工厂等级结构可以负责多个不同产品等级结构中的产品对象的创建。当一个工厂等级结构可以创建出分属于不同产品等级结构的一个产品族中的所有对象时,抽象工厂模式比工厂方法模式更为简单、更有效率

工厂模式的优点

  1. 把对象的创建和使用过程分开,对象创建和对象使用职责解耦
  2. 如果对象的创建过程很复杂, 创建过程放到工厂类里管理,即减少了重复代码,也方便维护
  3. 当业务扩展时,只需要增加工厂子类,符合开闭原则

参考博客

[1]https://www.kancloud.cn/digest/xing-designpattern/143724

[2]http://www.hollischuang.com/archives/1420