目录
一.工厂模式简介
- 工厂模式属于创建型模式;
- 在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象;
- 工厂模式的主要解决的问题是,将原来分布在各个地方的对象创建过程单独抽离出来,交给工厂类负责创建。其他地方想要使用对象直接找工厂(即调用工厂的方法)获取对象;
- 工厂模式可分为:简单工厂模式和工厂方法模式。其中简单工厂方法可看为工厂方法模式的特例;
二.代码实例
1.简单工厂模式
以一个简单的课程创建为例子:
先创建一个Course接口:
public interface Course {
public void begin();
}
创建三门课程,实现Course接口:
//English
public class English implements Course{
public English() {
}
@Override
public void begin() {
System.out.println("English class begins!");
}
}
//Math
public class Math implements Course{
public Math() {
}
@Override
public void begin() {
System.out.println("Math class begins!");
}
}
//History
public class History implements Course{
public History() {
}
@Override
public void begin() {
System.out.println("History class begins!");
}
}
创建一个Course工厂,来专门负责课程的创建,将创建课程对象的逻辑抽离出来,单独放到一个类中,这个类便是工厂类(专门生产Course的工厂)。这样维护起来便方便很多,客户端代码也无需知道对象创建的具体细节,只需要从工厂类中获取对象即可。
简单工厂实现方法如下:
public class CourseFactory {
public static Course getCourse(String str) {
if(str == null) {
return null;
}
if(str.equalsIgnoreCase("English")) {
return new English();
} else if(str.equalsIgnoreCase("Math")) {
return new Math();
} else if(str.equalsIgnoreCase("History")) {
return new History();
}
return null;
}
}
如下代码所示,要创建课程需要先创建一个CourseFactory对象,通过Course对象调用CourseFactory对象(课程工厂)来创建课程。
public class FactoryPatternDemo {
public static void main(String[] args) {
CourseFactory courseFactory = new CourseFactory();
Course course1 = courseFactory.getCourse("english");
course1.begin();
Course course2 = courseFactory.getCourse("History");
course2.begin();
Course course3 = courseFactory.getCourse("Math");
course3.begin();
}
}
hxdm来瞅一眼类图:
输出如下:
English class begins!
History class begins!
Math class begins!
2.工厂方法
- 在上面的简单工厂中,如果要创建的产品类型较多,且各个产品创建的过程不尽相同,则一个工厂类职责会变得越来越多,不符合单一职责原则。
- 另外简单工厂也不符合开闭原则。新增一种产品需要修改原来的工厂类。
- 因此,工厂方法模式中,将生产各种类型的产品的工厂做了抽象分离。比如,上面例子中的,生产英语课的有专门的英语工厂,生产历史课的有专门的历史工厂。
基于简单工厂的实例,我们继续来写代码:
先创建一个Course接口:
public interface Course {
public void begin();
}
创建三门课程,实现Course接口:
//English
public class English implements Course{
public English() {
}
@Override
public void begin() {
System.out.println("English class begins!");
}
}
//Math
public class Math implements Course{
public Math() {
}
@Override
public void begin() {
System.out.println("Math class begins!");
}
}
//History
public class History implements Course{
public History() {
}
@Override
public void begin() {
System.out.println("History class begins!");
}
}
再创建一个CourseFactory接口:
public interface CourseFactory {
public Course getCourse();
}
创建三个课程工厂,实现CourseFactory接口:
public class EnglishFactory implements CourseFactory{
public EnglishFactory() {
}
@Override
public Course getCourse() {
System.out.println("EnglishFactory: produce English Course!");
return new English();
}
}
public class HistoryFactory implements CourseFactory{
public HistoryFactory() {
};
@Override
public Course getCourse() {
System.out.println("HistoryFactory: produce History Course!");
return new History();
}
}
public class MathFactory implements CourseFactory{
public MathFactory() {
}
@Override
public Course getCourse() {
System.out.println("MathFactory: produce Math Course!");
return new Math();
}
}
如下代码所示,要创建一门课程,首先要创建相应的CourseFactory对象,然后创建出相应的课程工厂对象,再通过相应的课程工厂对象创建相应的Course对象:
public class FactoryPatternDemo {
public static void main(String[] args) {
CourseFactory factory = null;
factory = new EnglishFactory();
Course course1 = factory.getCourse();
course1.begin();
factory = new HistoryFactory();
Course course2 = factory.getCourse();
course2.begin();
factory = new MathFactory();
Course course3 = factory.getCourse();
course3.begin();
}
}
hxdm来瞅一眼类图:
输出如下:
EnglishFactory: produce English Course!
English class begins!
HistoryFactory: produce History Course!
History class begins!
MathFactory: produce Math Course!
Math class begins!
工厂方法适用于以下场景:
- 创建对象需要大量重复的代码;
- 客户端(应用层)不依赖于产品类实例如何被创建、实现等细节;
- 一个类通过其子类来指定创建哪个对象;
工厂方法也有缺点:
- 类的个数容易过多,增加复杂度。
- 增加了系统的抽象性和理解难度。
谢谢homie观看,欢迎指正!