设计模式--工厂方法模式和抽象工厂模式(Factory Pattern)

1、工厂模式的形式

    工厂模式专门负责将大量有共同接口的类实例化。工厂模式可以动态的决定将哪一个类实例化,工厂模式有以下几种形态:
    简单工厂(Simple Factory)模式:又称静态工厂方法(Static Factory Methord)模式。
    工厂方法(Factory Method)模式:又称多态性工厂(Polymorphic Factory)模式或虚拟构造子(Virtual Constructor)模式。
    抽象工厂(Abstract Factory)模式:又称工具箱(Kit或Toolkit)模式。

2、简单工厂模式优缺点

(1)简单工厂模式的优点
    核心式工厂类,工厂类决定在什么情况下创建哪一种产品类的实例。而客户端则可以免除直接创建产品对象的责任,而仅仅是“消费”产品。简单工厂模式通过这种做法实现了对责任的分割。
 
(2)简单工厂模式的缺点
    当产品类具有复杂的多层次等级结构时,工厂类只有它自己。以不变应万变,是其缺点。
这个工厂类集中了所有产品创建逻辑,形成了一个无所不知的全能类(也称上帝类),如果此类出问题了,整个应用都受大影响。
    当产品有多个接口时,判断在什么条件下创建什么产品类实例会很困难。
对于工厂来说,增加新的产品时一个痛苦的过程。工厂角色必须知道每一种产品,如何创建它们,以及何时向客户提供它们。换言之,接纳新的产品意味着修改这个工厂角色的源代码。简单工厂只在有限的程度上支持“开-闭”原则。
由于简单工厂模式使用静态方法作为工厂方法,而静态方法无法由子类继承,因此工厂角色无法形成基于继承的等级结构。这一缺点会在工厂方法模式中得到克服。

 

3、工厂方法模式

 (1)概念理解

    工厂方法模式是简单工厂模式的进一步抽象和推广。由于使用了多态性,工厂方法模式保持了简单工厂模式的优点,而且克服了它的缺点。
    在工厂方法模式中,核心的工厂类不再负责所有产品的创建,而是将具体创建的工作交给子类去做。这个核心工厂则变为抽象工厂角色,仅负责给出具工厂子类必须实现的接口,而不接触哪一产品创建的细节。

(2)例子

 

水果产品接口Fruit.java

public interface Fruit {
	/**
	 * 种植
	 */
	void plant();

	/**
	 * 生长
	 */
	void grow();

	/**
	 * 收获
	 */
	void harvest();
}

 

具体产品苹果Apple.java

public class Apple implements Fruit {
	private int treeAge;

	@Override
	public void grow() {
		System.out.println("Apple is growing...");
		
	}

	@Override
	public void harvest() {
		System.out.println("Apple has been harvested.");
	}

	@Override
	public void plant() {

		System.out.println("Apple has been planted.");
	}

	/**
	 * @return 返回树龄
	 */
	public int getTreeAge() {
		return treeAge;
	}

	/**
	 * 设置树龄
	 */
	public void setTreeAge(int treeAge) {
		this.treeAge = treeAge;
	}
}

具体产品葡萄:Grape.java
略...

具体产品草莓:Strawberry.java

略...

 

水果工厂接口:FruitGardener.java

public interface FruitGardener {
	/**
	 * 工厂方法
	 * 
	 * @return 水果
	 */
	public Fruit factory();
}
 

苹果工厂:AppleGardener.java

public class AppleGardener implements FruitGardener {
	@Override
	public Fruit factory() {
		Fruit f = new Apple();
		System.out.println("水果工厂(AppletGardener)成功创建一个水果:苹果!");
		return f;
	}
}

葡萄工厂:GrapeGardener.java
略...
草莓工厂:StrawberryGardener.java

略...

 

测试类(客户端):TestApp.java

 

public class TestApp {
	private FruitGardener f1, f2, f3;

	private Fruit p1, p2, p3;

	private void test() {
		// 实力化水果工厂
		f1 = new AppleGardener();
		f2 = new GrapeGardener();
		f3 = new StrawberryGardener();
		// 从水果工厂生产水果
		p1 = f1.factory();
		p2 = f2.factory();
		p3 = f3.factory();
	}

	public static void main(String args[]) {
		TestApp test = new TestApp();
		test.test();
	}

 

运行结果:

水果工厂(AppletGardener)成功创建一个水果:苹果!
水果工厂(GrapeGardener)成功创建一个水果:葡萄!
水果工厂(StrawberryGardener)成功创建一个水果:草莓!
Process finished with exit code 0

 

(3) 存在的缺点
有一个农业镇,这里有好几家农场。但每家农场生产的产品各不相同。
游客来到这里,想要买几种不同的水果回去,他必须要到几个农场去(因为:一家农场只卖一种水果)。

 

 

4、抽象工厂模式

(1)概念理解

    抽象工厂模式可以向客户端提供一个接口,使得客户端在不必指定产品具体类型的情况下,创建多个产品族中的产品对象。这就是抽象工厂模式的用意。
    每个模式都是针对一定问题的解决方案。抽象工厂模式面对的问题是多产品等级结构的系统设计。
    在学习抽象工厂具体实例之前,应该明白两个重要的概念:产品族和产品等级。
    产品族:是指位于不同产品等级结构中,功能相关联的产品组成的家族。比如AMD的CPU和ADM芯片的主板,组成一个家族。Intel的CPU和 Intel芯片的主板,又组成一个家族。而这两个家族都来自于两个产品等级:CPU,主板。

 

(2)例子

抽象工厂:Gardener.java

public interface Gardener {
	public Fruit createFruit(String name);

	public Veggie createVeggie(String name);
}

抽象水果产品:Fruit.java

 

public interface Fruit {
}
 

抽象蔬菜产品:Veggie.java

 

public interface Veggie {

}

热带水果:TropicalFruit.java

public class TropicalFruit implements Fruit {

	private String name;

	public TropicalFruit(String name) {
		System.out.println("热带工厂为您创建了:热带水果-" + name);
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}
 

热带蔬菜:TropicalVeggie.java

public class TropicalVeggie implements Veggie {
	private String name;

	public TropicalVeggie(String name) {
		System.out.println("热带工厂为您创建了:热带水果-" + name);
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}

 亚热带水果:NorthernFruit.java

public class NorthernFruit implements Fruit {

	private String name;

	public NorthernFruit(String name) {
		System.out.println("亚热带工厂为您创建了:亚热带水果-" + name);
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}

 亚热带蔬菜:NorthernVeggie.java

public class NorthernVeggie implements Veggie {
	private String name;

	public NorthernVeggie(String name) {
		System.out.println("亚热带工厂为您创建了:亚热带蔬菜-" + name);
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}

 热带工厂:TropicalGardener.java

public class TropicalGardener implements Gardener {

	@Override
	public Fruit createFruit(String name) {
		return new TropicalFruit(name);
	}

	@Override
	public Veggie createVeggie(String name) {
		return new TropicalVeggie(name);
	}
}

  亚热带工厂:NorthernGardener.java

public class NorthernGardener implements Gardener {

	@Override
	public Fruit createFruit(String name) {
		return new NorthernFruit(name);
	}

	@Override
	public Veggie createVeggie(String name) {
		return new NorthernVeggie(name);
	}
}

 测试类

public class TestApp {
	private FruitGardener f1, f2, f3;

	private Fruit p1, p2, p3;

	private void test() {
	
		Veggie tv,nv;
        Fruit tf,nf;
        Gardener tg=new TropicalGardener();
        Gardener ng=new NorthernGardener();
        tv=tg.createVeggie("热带菜叶");
        nv=ng.createVeggie("东北甜菜");
        tf=tg.createFruit("海南椰子");
        nf=ng.createFruit("雪梨");
	}

	public static void main(String args[]) {
		TestApp test = new TestApp();
		test.test();
	}
}

 结果:

热带工厂为您创建了:热带水果-热带菜叶
亚热带工厂为您创建了:亚热带蔬菜-东北甜菜
热带工厂为您创建了:热带水果-海南椰子
亚热带工厂为您创建了:亚热带水果-雪梨

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值