工厂模式和抽象工厂模式

1、工厂模式

当client不知道要创建哪一个具体类的实例,或者不想在client代码中指明要具体创建的实例;换句话说就是计划在不同条件下创建不同的实例。在这种情况下,适合使用个工厂模式。

工厂模式可以视作是一个虚拟的构造器,主要思路是定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
工厂模式的大致框架如下:(其中不同的Concrete为不同的构造方法,Product为具体构造的实例)

//常规情况下,client直接创建实例对象
Product p=new ProductOne();

//工厂模式下
Product p=new ConcreteOne.makeObject();

1.1 具体实例

问题背景:给定一个商店Shop1和其分店Shop2,两家店铺销售的商品相同,假设为Merchandise1和Merchandise2。模拟在两家店铺购买商品。

首先创建抽象产品类和两个具体产品的子类。

abstract class Merchandise{
	public abstract void show();//输出商品的相关信息
}

public class Merchandise1 extends Merchandise{//商品1
	private String name;
	private int num;
	private double price;
	...
	public Merchandise1(...){//构造函数
		...
	}
	@Override
	public void show(){
		System.out.println("...");//输出商品的详细信息
	}
	...
}


public class Merchandise2 extends Merchandise{//商品1
	private String name;
	private int num;
	private double price;
	...
	public Merchandise2(...){//构造函数
		...
	}
	@Override
	public void show(){
		System.out.println("...");//输出商品的详细信息
	}
	...
}

接下来创建商店类

abstract class Shop{//商店抽象类,定义两个抽象操作
	public abstract boolean add(Merchandise m);
	public abstract boolean delete(Merchandise m);
}

public class Shop1 extends Shop{//商店1
	private String name;
	private List<Merchandise> Merlist=new ArrayList<>();
	...
	@Override
	public boolean add(Merchandise m){
		if(Merlist.contain(m)) return false;//若已存在,添加失败
		Merlist.add(m);
		return true;
	}
	@Override
	public void delete(Merchandise m){
		if(!Merlist.contain(m)) return false;//若未存在,删除失败
		Merlist.remove(m);
		return true;
	}
}


public class Shop2 extends Shop{//商店2
	private String name;
	private List<Merchandise> Merlist=new ArrayList<>();
	...
	@Override
	public boolean add(Merchandise m){
		if(Merlist.contain(m)) return false;
		Merlist.add(m);
		return true;
	}
	@Override
	public void delete(Merchandise m){
		if(!Merlist.contain(m)) return false;
		Merlist.remove(m);
		return true;
	}
}	

然后创建工厂类。

interface Factory{
	public Shop CreateShop(String number);
}

public class Factory1 implements Factory{//工厂类
	@Override
	public Shop CreateShop(String number){
		if(number.equals("1")){
			return new Shop1();
		}
		else if(number.equals("2")){
			return new Shop2();
		}
		...
	}
	...
}

除了使用接口+子类的工厂模式,还可以使用静态工厂的模式。

public class Factory1 {//工厂类
	public static Shop CreateShop(String number){
		if(number.equals("1")){
			return new Shop1();
		}
		else if(number.equals("2")){
			return new Shop2();
		}
		...
	}
	...
}

最后就是在client通过工厂类创建商店

public class Client{
	Factory factory=new Factory().CreateShop("1");
	Merchandise m1=new Merchandise1(...);
	Merchandise m2=new Merchandise2(...);
	factory.add(m1);
	factory.delete(m2);
	...
}
  • 工厂模式的优点;Client想要创建一个对象,只需要知道名称即可;扩展性高,如果想增加一个产品,扩展一个工厂类就可以了;不出现产品的具体实现,符合防御型编程。
  • 工厂模式的缺点;每次增加一个产品时,都需要增加一个具体类和对象实现的工厂类,使得整个系统中类的个数增加较多,也增加了对系统具体类的依赖。

2、抽象工厂模式

当一个系统的产品有多于一个的产品族,而系统只消费其中某一族的产品时,可以使用抽象工厂模式。抽象工厂模式的大致思路是提供接口创建一组相关/相依赖的对象,且无需指明其具体类。
抽象工厂模式的大致框架:
在这里插入图片描述

2.1 实例

  • 问题背景;两种不同的操作系统Windows和Mac OS下的不同的应用程序。

首先创建的是两个操作系统的接口和相应的具体类(两个)。

//Windows系统
public interface Windows{
	public void view();//输出应用程序信息
	public void modify(String s);//修改应用程序信息
	...
}

public class WQQ implements Windows{//应用程序1
	private version;
	private name;
	...
	@Override
	public void view(){
		...
		System.out.println(...);
	}
	@Override
	public void modify(String s){
		...
	}
}

public class WWechat implements Windows{//应用程序二
	private version;
	private name;
	...
	@Override
	public void view(){
		...
		System.out.println(...);
	}
	@Override
	public void modify(String s){
		...
	}
}


//Mac OS 操作系统
public interface Mac{
	public void view();//输出应用程序信息
	public void modify(String s);//修改应用程序信息
	...
}

public class MQQ implements Window Mac{//应用程序1
	private version;
	private name;
	...
	@Override
	public void view(){
		...
		System.out.println(...);
	}
	@Override
	public void modify(String s){
		...
	}
}

public class MWechat implements Mac{//应用程序二
	private version;
	private name;
	...
	@Override
	public void view(){
		...
		System.out.println(...);
	}
	@Override
	public void modify(String s){
		...
	}
}

接下来定义抽象工厂接口和具体工厂类,,具体工厂类分别是QQ和Wechat在Windows和Mac操作系统下的创建。

public interface AbstractFactory{//抽象工厂接口
	public Windows CreateWindowsApp();
	public Mac CreateMacApp();
}

public class Factory1{//第一个具体工厂类
	public Windows CreateWindowsApp(){
		return new WQQ();
	}
	public Mac CreateMacApp(){
		return new MQQ();
	}
}

public class Factory2{//第二个具体工厂类
	public Windows CreateWindowsApp(){
		return new WWechat();
	}
	public Mac CreateMacApp(){
		return new MWechat();
	}
}

创建一个辅助类用于delegate到抽象工厂类,最后在Client创建实例。

public class Builder{
	public void build(AbstractFactory factory){
		Windows windows=factory.CreateWindowsApp();
		Mac mac=factory.CreateMacApp();
		...
	}
}

public Class Client{
	Builder builder=new Builder();
	AbstractFactory factory=null;
	Scanner input=new Scanner(System.in);
	if(input.nextLine().equals("QQ")){
		factory=new Factory1();
	}
	else if(input.nextLine.equals("WeChat")){
		factory=new Factory2();
	}
	...
	builder.build(factory);
}
  • AbstractFactory创建的不是一个完整的产品,而是一个产品族(遵循固定搭配规则的多类产品的实例),得到的结果是:多个不同产品的Object,各产品创建过程对Client可见,但搭配不能改变
  • 本质上,AbstractFactory是把多类产品的factory method组合在一起,而工厂模式的一个工厂子类只创建一类产品。
  • 抽象工厂的优点;新增一种产品类时,只需增加相应的具体产品类和相应的工厂子类即可;每个具体工厂类只负责创建对应的产品,而简单工厂类存在复杂的逻辑判断;不使用静态工厂方法,可以形成继承结构。
  • 抽象工厂的缺点;由于抽象工厂接口中已经确定了可以被创建的产品的集合,因此如果需要添加新产品,需要修改抽象工厂类的接口,相应地,所有工厂子类也要发生变化,比较麻烦,违法了开-闭原则。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值