设计模式(2)——工厂模式

合理的模式可以提高代码复用性,可维护性已经灵活性,下面介绍一下设计模式中的工厂模式,简单好用,也是上篇博文——面向接口编程  的更高一层的抽象。

 

面向接口将规范和实现分离,配合多态,使的代码的复用率提高,减少了代码量,比如说,我们不必为每一个对象写doEverything方法了,但是,当50个类中都需要new出person的话,我们还要在50个类中分别new出50个person,这似乎是必须的,但是当我们突然发现不应该new person,而应该new fox的时候,我们就需要到50个类中分别修改代码(这不是开闭原则..),不开心啊。。。。如果我们可以在将new 对象的动作放在一个统一的地方,只要在这个地方改一下,就可以将全局的person变成fox,岂不是大快人心。工厂来了,救星来了——更高一层的抽象。

 

工厂顾名思义,生产货品的地方,java中肯定是生产对象的地方,这里我们可以假设一个厂房有4个button,A,B,C,D分别对应person、cat、dog、fox,当我们发现person需要换成fox,简单,别按按钮A了,按下按钮D,fox就源源不断从流水线上出来了。是的,我们不再自己动手new对象了,而将这个动作托管给了工厂,当我们需要要某个对象的时候,只需要从工厂取就好了。

 

进入正题:

工厂模式分为两类:

1.工厂方法模式;(简单工厂模式是工厂方法模式的一个特例)

2.抽象工厂模式

 

先从最简单的简单工厂模式开始,先将该模式的几个角色定位一下:

1.工厂类角色:是具体产品类角色的构造者;(工厂模式,肯定要有工厂啦)

2.抽象产品角色:被工厂创建的对象;(之所以需要抽象产品,原因在面向接口编程中已经说过了)

3.具体产品角色:调用工厂类产生实例,并利用多态进行相应工作。(有抽象,就必须要有具体的实现类)

4.消费者角色:请求工厂生产实例(有生产就有买卖)

 

用上篇博文中(http://huntfor.iteye.com/admin/blogs/2024611)的例子:

 

package factoryPattern;

import Gof.Runable;

public class FactoryPattern {

	private static void doEverything(Runable runable) {
		System.out.println("now I am ready to run....");
		runable.run();
		System.out.println("I am tired and wanna walk for a while...");
		runable.walk();
		System.out.println("I am totally tired wanna stop....");
		runable.stop();
	}

	public static void main(String[] args) {

		// 将new 对象的工作托管给工厂,工厂实现对对象的统一管理
		Runable product = Factory.getByType('A');
		doEverything(product);
	}

}

class Factory {
	// 这里当然可以用非静态方法
	public static Runable getByType(char type) {
		if (type == 'A') {
			return new Person();
		} else if (type == 'B') {
			return new Cat();
		} else if (type == 'C') {
			return new Dog();
		} else if (type == 'D') {
			return new Fox();
		} else {
			return null;
		}
	}

}

class Person implements Runable {
	@Override
	public void run() {
		System.out.println("people run....");
	}

	@Override
	public void walk() {
		System.out.println("people walk....");
	}

	@Override
	public void stop() {
		System.out.println("people stop....");
	}
....下面的几个都一样
}

 这样,就对实例对象的产生有统一到了一个接口上(不再是狭义的interface),消费者直接与工厂这层接口交互,将new对象的过程又一次进行了封装。

 

 

工厂方法模式是简单工厂模式的衍生,并且解决了很多简单工厂模式存在的问题:

开闭原则要就我们对外可扩展,这里就暴露了简单工厂模式的局限性。现实生活中,一个工厂往往工作单一,比如说可口可乐公司只生产可乐,你可以生产各种汽水,比如雪碧,芬达,酷儿,醒目等等,但是你总不能生产空调吧。夏天即需要空调又需要可乐,怎么办?很简单啊,再建一个空调厂就可以了。问题又来了,这样的话,岂不是又要到处new 空调厂和可乐厂了?如果有必要,我们可以对这两个工厂再做一次工厂模式,建造一个生产工厂的工厂。

插句嘴:工厂方法模式是典型的模板方法模式的应用。后面再讲

 

工厂方法模式的框架

很简单,对每种产品建造响应的工厂。

下面简单实现一下:

产品接口:

package factoryPattern;

public interface IProduct {
	void function();
}

abstract class Cola implements IProduct{

	@Override
	public void function() {
		System.out.println("用於解渴");
	}
	public abstract void getMyBrand();
}

class CocoCola extends Cola{
	@Override
	public void getMyBrand() {
		System.out.println("我是可口可乐");
	}
}

class Sprite extends Cola{
	@Override
	public void getMyBrand() {
		System.out.println("我是雪碧");
	}
}


abstract class AirCondition implements IProduct{

	@Override
	public void function() {
		System.out.println("用于降温");
	}
	public abstract void getMyPower();
}

class Galanz extends AirCondition{
	@Override
	public void getMyPower() {
		System.out.println("我的功率是1P");
	}
}

class Midea extends AirCondition{
	@Override
	public void getMyPower() {
		System.out.println("我的功率是1.5P");
	}
}

 工厂接口:

public interface INormalFactory {
	IProduct produce(String type)throws Exception;
}

 工厂实现类:

package factoryPattern;

public class ColaFactory implements INormalFactory {

	@Override
	public IProduct produce(String type) throws Exception {
		if(type == "A"){
			return new CocoCola();
		}
		else if(type == "B"){
			return new Sprite();
		}else{
			throw new Exception("your type is not fund");
		}
	}
}

class AirConditionFactory implements INormalFactory {

	@Override
	public IProduct produce(String type)throws Exception {
		if(type =="A"){
			return new Galanz();
		}else if(type == "B"){
			return new Midea();
		}else{
			throw new Exception("your type is not fund");
		}
	}
	
	
}

 消费者角色:(我画蛇添足的加了一点反射以及抽象类,如果不是很清楚的,可以先简单看一下反射)

package factoryPattern;

public class NormalFactoryTest {
	
	static void getDetail(IProduct product) throws InstantiationException, IllegalAccessException{
		product.function();
		if(product instanceof Cola){
			if(product.getClass().newInstance() instanceof Cola){
				((Cola)product).getMyBrand();
			}
			
		}else if(product instanceof AirCondition){
			if(product.getClass().newInstance() instanceof Galanz){
				((Galanz)product).getMyPower();
			}else if(product.getClass().newInstance() instanceof Midea){
				((Midea)product).getMyPower();
			}
		}
	}
	
	public static void main(String[] args) throws Exception {
		
		INormalFactory colaFactory = new ColaFactory();
		INormalFactory airContidionFactory = new AirConditionFactory();

		IProduct cocoCola = colaFactory.produce("A");
		IProduct sprite = colaFactory.produce("B");
		IProduct glanze =  airContidionFactory.produce("A");
		IProduct midea =  airContidionFactory.produce("B");
		
		getDetail(cocoCola);
		getDetail(sprite);
		getDetail(glanze);
		getDetail(midea);
		
	}
	
}

 以上是工厂方法模式。

 

抽象工厂模式是所有工厂模式中最具一般性的形态,因而也更抽象。会专门用一篇博文做详细的解释。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值