二、创建型模式:抽象工厂模式(Abstract Factory)

         追MM少不了请吃饭了,麦当劳的套餐和肯德基的套餐都是MM爱吃的东西,虽然口味有所不同,但不管你带MM去麦当劳或肯德基,只管向服务员说“两个B套餐”就行了。麦当劳和肯德基就是B套餐的Abstract Factory, B套餐里含有汉堡, 鸡翅和饮料. 麦当劳或肯德基会根据B套餐的规格, 让汉堡Factory, 鸡翅Factory, 饮料Factory分别生产对应B套餐的材料.


定义  
         有称作“工具箱”模式,提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。



使用场景

        一个系列要独立于它的产品的创建、组合和表示时。
        一个系统要由多个产品系列中的一个来配置时。
        当要强调一系列相关的产品对象的设计以便进行联合使用时。
        当要提供一个产品类库,而只要显示它们的接口而不是实现时。
        简单的说就是适用于客户端中经常需要切换配置(交换产品系列)时,客户端通过抽象接口来操纵实例,具体的类名不会出现在客户端中。



优缺点分析

  优点 缺点
简单工厂模式
  • 分离了客户端和后台逻辑,使得客户端无需关心后台的实现,去除了客户端与具体产品的依赖,增强了移植性能。
  • 实现简单,易于操作。
  • 违背了开放-封闭原则
  • 添加新产品时比较麻烦
工厂方法模式
  • 是简单工厂模式的升级
  • 易于添加新产品
  • 后台模块契合了开放-封闭原则
  • 新产品的添加带来了大量新的类的创建,增加了工作量
  • 客户端部分仍然违反开放-封闭原则,只是后台判断逻辑挪到了前台
抽象工厂模式
  • 分离了具体的类,工厂封装了创建产品对象的责任和过程,将客户端和类的实现分离,客户端通过抽象接口操纵实例
  • 易于交换产品系列,一个具体的工厂类在一个应用中仅在初始化时出现一次,改变一个应用的具体工厂变得容易
  • 有利于产品的一致性,一个系列中的产品对象被设计成一起工作时,一个应用一次只能使用同一系列中的对象
  • 难以支持新种类的产品,抽象工厂接口确定了可以被创建的产品集合。新种类产品加入需要扩展抽象工厂接口,这就涉及到了接口本身和所有实现类的改变



角色及其职责
抽象工厂(Abstract Factory)角色: 担任这个角色的是工厂方法模式的核心,它是与应用系统商业逻辑无关的。
具体工厂(Concrete Factory)角色: 这个角色直接在客户端的调用下创建产品的实例。这个角色含有选择合适的产品对象的逻辑,而这个逻辑是与应用系统的商业逻辑紧密相关的。
抽象产品(Abstract Product)角色: 担任这个角色的类是工厂方法模式所创建的对象的父类,或它们共同拥有的接口。
具体产品(Concrete Product)角色: 抽象工厂模式所创建的任何产品对象都是某一个具体产品类的实例。这是客户端最终需要的东西,其内部一定充满了应用系统的商业逻辑。



抽象工厂模式UML图


应用场景及代码分析
       程序员小明使用工厂方法模式对面包店进行了一番改造,效果显著,加入新的面包时变得容易了,可是,小明的生意做的越来越大,并不满足只卖面包了,他想在自己的店里面加入自己喜欢吃的披萨,于是按照他开始了编码的道路
       首先将我们的面包师和面包写出来:

//面包师,作为父类
public class BreadMaker {
	//生产面包
	public  void getBread(){
		//等待孩子们生产出来
	}
}

//奶油面包
public class ButterBread extends BreadMaker{
	// 覆盖父类方法
	@Override
	public void getBread() {
		// TODO Auto-generated method stub
		super.getBread();
		System.out.println("烤出了奶油面包");
	}
}

//巧克力面包
public class ChocolateBread extends BreadMaker{
	// 覆盖父类方法
	@Override
	public void getBread() {
		// TODO Auto-generated method stub
		super.getBread();
		System.out.println("烤出了巧克力面包");
	}
}

//香蕉面包
public class BananaBread extends BreadMaker{
	// 覆盖父类方法
	@Override
	public void getBread() {
		// TODO Auto-generated method stub
		super.getBread();
		System.out.println("烤出了香蕉面包");
	}
}



同样,类似于面包师和面包,也创建出了披萨师和各种披萨
//披萨师 各种披萨的父类
public class PizzaMaker {
	//制作披萨
	public void GetPizza(){
		
	}
}

//奶油披萨
public class ButterPizza extends PizzaMaker {

	@Override
	public void GetPizza() {
		// TODO Auto-generated method stub
		super.GetPizza();
		System.out.println("制作出了奶油披萨");
	}
}

//巧克力披萨
public class ChocolatePizza extends PizzaMaker {

	@Override
	public void GetPizza() {
		// TODO Auto-generated method stub
		super.GetPizza();
		System.out.println("制作出了巧克力披萨");
	}
}

//香蕉披萨
public class BananaPizza extends PizzaMaker {

	@Override
	public void GetPizza() {
		// TODO Auto-generated method stub
		super.GetPizza();
		System.out.println("制作出了香蕉披萨");
	}
}


写到这里,按照之前工厂方法模式的方法,还需要添加新的工厂接口和3个披萨实体类对应的工厂实体类,小明突然发现这样做的成本太大了,回头想了想,原来披萨和面包的制作方法都是相似的嘛,完全可以放在一起制作啊,对于顾客来说,他们并不关心面包和披萨在哪里做出来的,关心的是面包和披萨的直接、快速取得。于是在同一个工厂里加入了披萨工厂。
//工厂接口
public interface IFactory {
	BreadMaker createBread();
	//增加了返回披萨实例的接口方法
	PizzaMaker createPizzer();
}

//奶油面包和奶油披萨的工厂方法实现
public class ButterBreadFactory implements IFactory{

	@Override
	public BreadMaker createBread() {
		//返回奶油面包实例
		return new ButterBread();
	}

	@Override
	public PizzaMaker createPizzer() {
		// 返回奶油披萨实例
		return new ButterPizza();
	}
}

//巧克力面包和巧克力披萨的工厂方法实现
public class ChocolateBreadFactory implements IFactory{
	@Override
	public BreadMaker createBread() {
		//返回巧克力面包实例
		return new ButterBread();
	}

	@Override
	public PizzaMaker createPizzer() {
		// 返回巧克力披萨实例
		return null;
	}
}


//香蕉面包和香蕉披萨的工厂方法实现
public class BananaBreadFactory implements IFactory{
	@Override
	public BreadMaker createBread() {
		//返回香蕉面包实例
		return new ButterBread();
	}

	@Override
	public PizzaMaker createPizzer() {
		//返回香蕉披萨实例
		return null;
	}
}


现在小明又开始重新开张了:
//抽象工厂模式测试
public class AbstractFactoryTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println("小明面包披萨店开始营业!");
		BreadMaker breadMaker = null;
		PizzaMaker pizzaMaker = null;
		IFactory breadFactory = null;
		System.out.println("顾客要一个奶油面包");
		//根据需要实例化接口
		breadFactory = new ButterBreadFactory();
		breadMaker =breadFactory.createBread();
		breadMaker.getBread();
		
		System.out.println("顾客要一个奶油披萨");
		pizzaMaker =breadFactory.createPizzer();
		pizzaMaker.GetPizza();
	}
}


输出结果:
小明面包披萨店开始营业!
顾客要一个奶油面包
烤出了奶油面包
顾客要一个奶油披萨
制作出了奶油披萨




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值