工厂模式
工厂方法模式
工厂方法模式:定义一个创建产品对象的工厂接口,将实际创建性工作推迟到子类中。
分类:简单工厂、工厂方法、抽象工厂
简单工厂
工厂类处于对产品类实例化的中心位置上,它知道每一个产品,决定哪一个产品类应当被实例化。
示例:
/**
* 简单工厂模式
* @author zhurong
* @create 2021/1/31
*/
public interface Shape {
void draw();
}
/**
* @author zhurong
* @create 2021/1/31
*/
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("-------画了一个矩形------");
}
}
/**
* @author zhurong
* @create 2021/1/31
*/
public class Square implements Shape {
@Override
public void draw() {
System.out.println("-------画了一个正方形------");
}
}
/**
* @author zhurong
* @create 2021/1/31
*/
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("-------画了一个圆------");
}
}
定义工厂:
/**
* @author zhurong
* @create 2021/1/31
*/
public class ShapeFactory {
public Shape getShape(String shapeType){
if (shapeType==null){
return null;
}
if (shapeType.equalsIgnoreCase("CIRCLE")){
return new Circle();
}else if (shapeType.equalsIgnoreCase("SQUARE")){
return new Square();
}else if (shapeType.equalsIgnoreCase("RECTANGLE")){
return new Rectangle();
}
return null;
}
}
测试类:
/**
* @author zhurong
* @create 2021/1/31
*/
public class FactoryTest {
public static void main(String[] args) {
//简单工厂模式
ShapeFactory factory = new ShapeFactory();
Shape shape1 = factory.getShape("circle");
shape1.draw();
Shape shape2 = factory.getShape("square");
shape2.draw();
Shape shape3 = factory.getShape("rectangle");
shape3.draw();
}
}
简单工厂模式的优点:允许客户端相对独立于产品创建过程,并在系统引入新产品的时候无需修改客户端。
简单工厂模式的缺点:对“开-闭”原则不够支持,从上面的ShapeFactory
可以看出,如果有新产品加入系统,则需要修改工厂类,加入相关逻辑。
工厂方法模式
工厂方法模式是对简单工厂的进一步抽象,体现在哪里呢?
首先,产品的创建不再全部通过ShapeFactory
,而是交给了子类;
其次,工厂核心类仅负责给出具体工厂类必须实现的接口,将实现细节交给了子类。
这种改进使得系统在引入新产品的时候无需修改具体工厂角色,从而客服了简单工厂模式的缺点。
示例:;
public interface Creator {
public <T extends Product> T factory(Class<T> c);
}
/**
* @author zhurong
* @create 2021/1/31
*/
public interface Product {
void method1();
void method2();
}
/**
* @author zhurong
* @create 2021/1/31
*/
public class ConcreteCreaor implements Creator {
@Override
public <T extends Product> T factory(Class<T> c) {
Product product = null;
try {
product= (Product) Class.forName(c.getName()).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return (T) product;
}
}
/**
* @author zhurong
* @create 2021/1/31
*/
public class ConcreteProduct implements Product{
@Override
public void method1() {
}
@Override
public void method2() {
}
}
抽象工厂模式
定义:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。是工厂方法模式的升级版本,在有多个业务品种及业务分类时,需要通过抽象工厂模式产生需要的对象。
类图:
两者区别:工厂方法模式针对一个产品结构,而抽象工厂模式针对多个产品结构。举个例子,一个果园里有多种水果要生产,比如葡萄、苹果、香蕉等,生产多种水果,就是抽象工厂模式,若果园只有一种水果,则抽象工厂模式退化为工厂方法模式。
示例:
/**
* @author zhurong
* @create 2021/1/31
*/
public interface AbstractFactory {
public ProductA factoryA();
public ProductB factoryB();
}
首先定义一个抽象工厂,给出两种产品的实现接口方法
/**
* @author zhurong
* @create 2021/1/31
*/
public class ConcreteFactory1 implements AbstractFactory{
@Override
public ProductA factoryA() {
return new ProductA1();
}
@Override
public ProductB factoryB() {
return new ProductB1();
}
}
public class ConcreteFactory2 implements AbstractFactory{
@Override
public ProductA factoryA() {
return new ProductA2();
}
@Override
public ProductB factoryB() {
return new ProductB2();
}
}
然后定义两种具体产品种类的实现
/**
* @author zhurong
* @create 2021/1/31
*/
public interface ProductA {
void method1();
void method2();
}
接着定义产品种类A的实现
/**
* @author zhurong
* @create 2021/1/31
*/
public class ProductA1 implements ProductA{
@Override
public void method1() {
System.out.println("种类为A的产品A1实现方法");
}
@Override
public void method2() {
}
}
定义产品种类A中名称为A1的产品实现
/**
* @author zhurong
* @create 2021/1/31
*/
public class ProductA2 implements ProductA{
@Override
public void method1() {
System.out.println("种类为A的产品A2实现方法");
}
@Override
public void method2() {
}
}
定义产品种类A中名称为A2的产品实现
/**
* @author zhurong
* @create 2021/1/31
*/
public interface ProductB {
void method1();
void method2();
}
定义产品种类B
public class ProductB1 implements ProductB{
@Override
public void method1() {
System.out.println("种类为B的产品B1实现方法");
}
@Override
public void method2() {
}
}
定义产品种类B中名称为B1的产品实现
/**
* @author zhurong
* @create 2021/1/31
*/
public class ProductB2 implements ProductB{
@Override
public void method1() {
System.out.println("种类为B的产品B2实现方法");
}
@Override
public void method2() {
}
}
定义产品种类B中名称为B2的产品实现
最后是测试代码:
//抽象工厂模式
AbstractFactory factory1=new ConcreteFactory1();
AbstractFactory factory2=new ConcreteFactory2();
factory1.factoryA().method1();
factory1.factoryB().method1();
factory2.factoryA().method1();
factory2.factoryB().method1();
输出:
种类为A的产品A1实现方法
种类为B的产品B1实现方法
种类为A的产品A2实现方法
种类为B的产品B2实现方法
以上是三种工厂模式的示例,可以看出抽象工厂方法涵盖的范围最大,可以针对不同种族的产品定义不同的实现,用户无需关心产品的创建细节,只需要通过工厂即可直接生产。
抽象工厂模式的最大缺点是:产品族本身的扩展很困难,如果需要在产品族种增加一个新的产品类型,几乎所有接口都需要改动。
使用场景:当一个对象簇都有相同约束时可用抽象工厂模式。