定义:
定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类。工厂方法让类的实例化推迟到子类中进行。
类型:
创建型。
适用场景:
创建对象需要大量重复的代码;
客户端(应用层)不依赖于产品类实例如何被创建、实现等细节;
一个类通过其子类来指定创建哪个对象。
优点:
用户只需要关心所需产品对应的工厂,无需关心创建细节,加入新产品符合开闭原则,提高可扩展性。
缺点:
类的个数容易过多,增加复杂度。
增加了系统的抽象性和理解难度。
代码实现:
- 创建抽象video类:
package com.design.pattern.creational.factorymethod;
public abstract class Video {
public abstract void produce();
}
- video的实现类:
package com.design.pattern.creational.factorymethod;
public class JavaVideo extends Video {
@Override
public void produce() {
System.out.println("录制Java课程视频");
}
}
package com.design.pattern.creational.factorymethod;
public class PythonVideo extends Video {
@Override
public void produce() {
System.out.println("录制Python课程视频");
}
}
- 创建工厂类:
package com.design.pattern.creational.factorymethod;
public abstract class VideoFactory {
public abstract Video getVideo();
}
- 将具体实现交给子类:
package com.design.pattern.creational.factorymethod;
class JavaVideoFactory extends VideoFactory {
@Override
public Video getVideo() {
return new JavaVideo();
}
}
package com.design.pattern.creational.factorymethod;
public class PythonVideoFactory extends VideoFactory {
@Override
public Video getVideo() {
return new PythonVideo();
}
}
- 进行测试:
package com.design.pattern.creational.factorymethod;
public class Test {
public static void main(String[] args){
VideoFactory videoFactory = new JavaVideoFactory();
Video video = videoFactory.getVideo();
video.produce();
}
}
将每一个类的实现实例推迟到子类,当需要新建类的时候,直接创建新类即可,不需要进行修改。满足开闭原则。
例如新增一个Web视频:
package com.design.pattern.creational.factorymethod;
public class WebVideo extends Video{
@Override
public void produce() {
System.out.println("录制Web课程视频");
}
}
package com.design.pattern.creational.factorymethod;
public class WebVideoFactory extends VideoFactory{
@Override
public Video getVideo() {
return new WebVideo();
}
}
工厂方法在源码中的体现:
Collection类的iterator就是一个工厂方法,而整体的Collection可以理解成抽象工厂。
此外,URLStreamHandlerFactory类(接口),LoggerFactory也是工厂方法的实现的体现。