java设计模式之抽象工厂

为什么要有抽象工厂

  • 如果在上一篇工厂方法的介绍中多了,要把源码加进去,那么必须新增源码的抽象类,几个具体的实现类,对应的工厂抽象类,对应的具体工厂实现类。类一下子多到爆炸。而我们前面强调了,Java源码和Python源码属于同一产品等级,而源码和视频属于同一产品族。解决前者用工厂方法,解决后者用抽象工厂。

抽象工厂案例

1. 类图

在这里插入图片描述

2. 代码

package com.joncy.abstractFactory;

public abstract class Code {
	public abstract void produce();
}

package com.joncy.abstractFactory;

public class PythonCode extends Code{

	@Override
	public void produce() {
		System.out.println("prthon-code");
	}

}

package com.joncy.abstractFactory;

public class JavaCode extends Code{

	@Override
	public void produce() {
		System.out.println("java-code");
	}

}

package com.joncy.abstractFactory;

public abstract class Video {
	public abstract void produce();
}

package com.joncy.abstractFactory;

public class PythonVideo extends Video{

	@Override
	public void produce() {
		System.out.println("python-video");	
	}
	
}
package com.joncy.abstractFactory;

public class JavaVideo extends Video{

	@Override
	public void produce() {
		System.out.println("java-video");
	}
	
}

package com.joncy.abstractFactory;

public interface CourseFactory {
	Video getVideo();
	Code getCode();
}
package com.joncy.abstractFactory;

public class PythonCourseFactory implements CourseFactory{

	@Override
	public Video getVideo() {
		return new PythonVideo();
	}

	@Override
	public Code getCode() {
		return new JavaCode();
	}

}

package com.joncy.abstractFactory;

public class JavaCourseFactory implements CourseFactory{

	@Override
	public Video getVideo() {
		return new JavaVideo();
	}

	@Override
	public Code getCode() {
		return new JavaCode();
	}

}

package com.joncy.abstractFactory;

public class Application {
	public static void main(String[] args) {
		//如果是抽象工厂方法将同属一个产品族的产品放入到同一工厂中,保证不会拿错
		CourseFactory courseFactory = new JavaCourseFactory();
		Video javaVideo = courseFactory.getVideo();
		Code javaCode = courseFactory.getCode();
		javaVideo.produce();
		javaCode.produce();
	}
}

概念 & 原理

1. 定义

  • 抽象工厂模式提供了一个创建**一系列相关(产品族和产品等级)**或相互依赖对象的接口。
  • 类型:创建型
  • 无须指定他们具体的类:将一组具有同一主题的单独的工厂封装起来,在正常使用中,客户端程序需要创建工厂的具体实现,然后使用抽象接口来创建这一主题的对象,我们在使用的时候,是不需要关心它从这些内部方法中获取对象的具体过程。抽象工厂将一组对象的实现细节和它们的使用分离开来

2.适用场景

  • 客户端(应用层)不依赖于产品类实例如何被创建、实现的细节。
  • 强调一系列相关的产品对象(同属同一产品族)一起使用创建对象需要大量的重复代码
  • 提供了一个产品类的库,所有产品以同样的接口出现,从而使客户端不依赖于具体实现

3. 优缺点

  • 优点:
    • 具体的产品在应用层代码隔离(所有的工厂都具有),无须关心创建细节。应用层代码不和具体的产品发生依赖,它只和具体的产品族工厂发生依赖关系。
    • 将一个系列的产品统一到一起创建。从具体的产品族工厂取出来的肯定属于同一产品族
    • 扩展性好,新增算法产品族,只需增加算法的工厂,和对应的产品类,符合开闭原则
  • 缺点:
    • 规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂的接口,需要进行大的修改,违背了开闭原则。所以要找相对固定的(时间很久才会改一次)
    • 增加了系统的抽象性和理解难度

4. 产品等级 & 产品族

在这里插入图片描述

5. 抽象工厂 or 工厂方法?

  • 当一个工厂可以创建出分属于不同产品等级结构的一个产品族的对象时,抽象工厂更具效率,因为类的个数变少了
  • 两者类数对比,可以发现只是多了一个产品等级,原来的工厂中单一产品等级变成了多个。
    在这里插入图片描述

6. 重要总结

  • 从应用层代码就可以看出,它根本不关心什么视频还是代码之类的,它只关心从哪个工厂里面拿到对应的产品。 从java课程里面拿视频,拿源码,肯定不会拿错。应用层即使和具体的实现类不再一个包中,也不需要导入对应实现类的包,依赖关系很少。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值