工厂方法案例
1. 类图
2. 代码
package com.joncy.factoryMethod;
//产品等级,产品族.工厂方法解决前者,抽象工厂解决后者
public abstract class Video {
public abstract void produce();
}
package com.joncy.factoryMethod;
public class JavaVideo extends Video{
@Override
public void produce() {
System.out.println("生产 JAVA 视频");
}
}
package com.joncy.factoryMethod;
public class PythonVideo extends Video{
@Override
public void produce() {
System.out.println("生产 Python 视频");
}
}
package com.joncy.factoryMethod;
/**
*
* @author Joncy Zhang
* 为什么使用抽象类?因为在实际的业务场景,我们的抽象类有可能对于某些行为、属性是已知的。所以
* 这里面除了抽象方法,还有一些已知的实现。如果里面全是未知的,我们可以用接口来定义
*/
public abstract class VideoFactory {
public abstract Video getVideo();
}
package com.joncy.factoryMethod;
public class JavaVideoFactory extends VideoFactory {
@Override
public Video getVideo() {
return new JavaVideo();
}
}
package com.joncy.factoryMethod;
public class PythonVideoFactory extends VideoFactory{
@Override
public Video getVideo() {
return new PythonVideo();
}
}
package com.joncy.factoryMethod;
import org.junit.jupiter.api.Test;
public class Application {
@Test
public void test() {
VideoFactory videoFactory1 = new JavaVideoFactory();
Video javaVideo = videoFactory1.getVideo();
javaVideo.produce();
VideoFactory videoFactory2 = new PythonVideoFactory();
Video pythonVideo = videoFactory2.getVideo();
pythonVideo.produce();
}
}
运行结果:
工厂方法概念与原理
1. 定义
- 定义创建对象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方法让类的实例化推迟到子类中进行
- 类型:创建型
2.适用场景
- 创建对象需要大量重复代码
- 客户端(应用层)不依赖于产品类实例如何被创建、实现等细节
- 一个类通过其子类来指定创建哪个对象
不需要知道具体产品的类名,只需要知道生产产品的工厂就可以。有人可能回想,知道工厂类名不就可以倒推出产品的类名?实际不是这样的,我们在案例中知识为了方便理解写成这样而已。
还记得简单工厂的缺点吗?它的工厂负责的职责太多了,而抽象工厂,将生成产品推给子类,每个子类负责一个产品。
我们可以总结一下,无论是简单工厂,还是工厂方法,都在做一件事情,那就是封装具体类的生成细节,也就是new对象的过程。
3. 优缺点
- 优点:用户只需要关心所需产品对应的工厂,无须关心创建细节;加入新产品符合开闭原则,提高可扩展性。
- 缺点:类的个数容易过多(从案例就知道,在添加产品的时候,不仅要加产品类,还要加产品的工厂类),增加复杂度。增加了系统的抽象性和理解难度