创建型-抽象工厂学习

1、抽象工厂模式的意图;

  提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

 

2、抽象工厂模式的适用性;

  • 一个系统要独立于它的产品的创建、组合和表示时。
  • 一个系统要由多个产品系列中的一个来配置时。
  • 当你要强调一系列相关的产品对象的设计以便进行联合使用时。
  • 当你提供一个产品类库,而只想显示它们的接口而不是实现时。

3、场景描述;

  考虑一个生产多种不同风格的家具的工厂(FurnitureFactory),不同风格的家具系列可以提供不同的门、窗、地板等的组合,为同一所住房可以提供不同的外观和行为。

 

4、抽象工厂模式类图;

  

  角色

  • AbstractFactory:提供给用户类Client使用工厂创建对象的接口;
  • Client:用户类;
  • ConcreteFactory1、ConcreteFactory2:AbstractFactory类的具体实现类,包含了创建具体对象的方法;封装了不同的具体产品作为一个系列(如ProductA1、ProductB1、ProductC1);
  • ProductA1、ProductA2:一般具有相同的父类ProductA,但是ProductA1、ProductA2提供了不同的展现形式;

5、代码实现;

  5.1 工程结构图;

  

  5.1.2实例类图;

   
   实例类图中的类基本对应设计模式的一般化类图。

   其中FurnitureFactory是接口,ExpensiveDoor是Door的子类,ExpensiveFloor是Floor的子类,ExpensiveWindow是Window的子类。

  5.2实践;
    5.2.1 基本组件类;

    Window.java

package com.crazysnail.furnitures;

public class Window {
	public Window(){
		System.out.println("I'm a ordinary window");
	}
}

   Floor.java

package com.crazysnail.furnitures;

public class Floor {
	public Floor(){
		System.out.println("I'm a ordinary floor.");
	}
}

    Door.java

package com.crazysnail.furnitures;

public class Door {
	public Door(){
		System.out.println("I'm a ordinary door.");
	}
}

   ExpensiveWindow.java 

package com.crazysnail.furnitures;

public class ExpensiveWindow extends Window {
	public ExpensiveWindow(){
		System.out.println("I'm a expensive window.");
	}
}

   ExpensiveFloor.java 

package com.crazysnail.furnitures;

public class ExpensiveFloor extends Floor {
	public ExpensiveFloor(){
		System.out.println("I'm a expensive floor");
	}
}

    ExpensiveDoor.java 

package com.crazysnail.furnitures;

public class ExpensiveDoor extends Door{
	public ExpensiveDoor(){
		System.out.println("I'm a expensive door.");
	}
}

    5.2.2工厂类;

    FurnitureFactory.java

package com.crazysnail.abstractfactory;

//抽象工厂模式中对外开放的接口,接口中定义了抽象工厂能够生产的产品种类
public interface FurnitureFactory{
	public Window createWindow();
	public Floor createFloor();
	public Door createDoor();
}

    OrdinaryFurnitureFactory.java 

package com.crazysnail.abstractfactory;

//普通家具的工厂类,组合了普通的Window、Floor、Door类作为一个系列来使用
public class OrdinaryFurnitureFactory implements FurnitureFactory {
	@Override
	public Window createWindow() {
		return new Window();
	}
	@Override
	public Floor createFloor() {
		return new Floor();
	}
	@Override
	public Door createDoor() {
		return new Door();
	}
}

   ExpensiveFurnitureFactory.java 

package com.crazysnail.abstractfactory;

//昂贵家具工厂类,组合了昂贵的ExpensiveWindow、ExpensiveFloor、ExpensiveDoor类,作为一个系列来使用
public class ExpensiveFurnitureFactory implements FurnitureFactory {
	@Override
	public Window createWindow() {
		return new ExpensiveWindow();
	}
	@Override
	public Floor createFloor() {
		return new ExpensiveFloor();
	}
	@Override
	public Door createDoor() {
		return new ExpensiveDoor();
	}
}

   5.2.3 使用抽象工厂举例;

    DecoretionCompany.java 

package com.crazysnail.abstractfactory;

/**
 * 
 * 
 * 易于交换产品系列
 * 有利于控制产品的一致性,控制使用相同系列的门、窗、地板
 * 提供给用户的都是一些系列化的产品
 * 
 * But,难以支持新种类的产品;
 * 
 * 提供给用户的接口仅仅是不同的家具工厂,但是用户并不知晓具体的类
 *
 */
public class DecorationCompany {
	public void decorateHouse(FurnitureFactory factory, House house){
		Window window = factory.createWindow();
		Door door = factory.createDoor();
		Floor floor = factory.createFloor();
		
		/*装饰*/
		house.addWindow(window);
		house.addDoor(door);
		house.addFloor(floor);
	}
}

6、总结;

  6.1 抽象工厂的优点;

  • 分离了具体的类——提供给用户类的接口仅仅是抽象工厂类及其子类,隐藏了组件类的具体实现。
  • 使得易于交换产品系列——在用户类中使用时,可以很方便的替换产品的系列,如只要DecorationCompany类中的decorateHouse方法中factory参数,便可以替换整个样式。
  • 有利于产品的一致性——将一组不同的组件组成一个系列来使用,如例子中的将Window、Door、Floor封装到OrdinaryFurnitureFactory中作为一个系列使用,将ExpensiveWindow、ExpensiveDoor、ExpensiveFloor封装到ExpensiveFurnitureFactory中来作为一个系列来使用。

  6.2 抽象工厂的缺点;

  •   难以支持新种类的产品——若要能够生产新的产品,则需要同时修改抽象工厂类及其子类。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值