工厂模式

原创 2016年08月31日 23:22:22

一、 简单工厂

先来思考一个问题。我们平时写程序时,会有这种情况,A对象里面需要调用B对象的方法,这时我们使用的一般是new关键字来创建一个B实例,然后调用B实例的方法。这种做法的坏处在于:A类的方法实现直接调用了B类的类名(这种方式也被称为硬编码耦合),一旦系统需要重构:需要使用C类来代替B类时,程序就不得不修改A类代码,如果应用中有100个或者10000个类以硬编码方式耦合了B类,则需要修改100个、10000个地方,这显然是一种非常可怕的事情。

换一个角度来看这个问题:对已A对象而言,它只需要调用B对象的方法,并不关心B对象的实现、创建过程,考虑让B类实现一个IB接口,而A类只需要与IB接口耦合——A类并不直接使用new关键字来创建B实例,而是重新定义一个工厂类:IBFactory,由该工厂类负责创建IB实例,而A类用过调用IBFactory工厂的方法来得到IB的实例。通过以上设计:需要使用C类代替B类,则只需要让C类也实现IB接口,并改写IBFactory工厂中创建IB实例的实现代码,让该工厂产生C实例即可。这种将多个类对象交给工厂类来生成的设计方式叫做简单工厂模式。

以下是简单工厂模式的代码:

/**
 * 简单工厂模式
 * 
 * 需要工厂生产的对象实例所实现的共同的接口
 * 发型接口
 * @author Administrator
 *
 */
public interface Hair {

	/**
	 * 画发型
	 */
	public void draw();
}
/**
 * 左偏分发型
 * @author Administrator
 *
 */
public class LeftHair implements Hair {

	@Override
	public void draw() {
		System.out.println("----------------画左偏分发型-----------------");
	}

}
/**
 * 右偏分发型
 * @author Administrator
 *
 */
public class RightHair implements Hair {

	@Override
	public void draw() {
		System.out.println("-----------------画右偏分发型------------------");
	}

}
/**
 * 生产发型的工厂
 * 要生产什么发型 只需在这里改就行了
 * @author Administrator
 *
 */
public class HairFactory {

	public Hair getHair() {
		return new LeftHair();
		//return new RightHair();
	}
}
/**
 * 客户端测试类
 * @author Administrator
 *
 */
public class HairTest {

	public static void main(String[] args) {
		HairFactory factory = new HairFactory();
		Hair hair = factory.getHair();
		hair.draw();
	}
}

可以看到,如果想把HairTest里面生成的LeftHair改成RightHair,只需修改HairFactory里面getHair方法的实现即可。

使用简单工厂模式的优势在于:让对象的调用者和对象的创建过程分离,当对象调用者需要对象时,直接向工厂请求即可,从而避免了对象的调用者与对象实现类以硬编码方式耦合,以提高系统的可维护性、可扩展性。当然,工厂模式也有一个小小的缺陷,当产品修改时,工厂类也要做相应的修改,此处可使用策略模式进行解决,下面是代码。

public interface HairBuilder {
	/**
	 * 制造发型
	 * @return
	 */
	public Hair getHair();
}
public class LeftHairBuilder implements HairBuilder {

	@Override
	public Hair getHair() {
		return new LeftHair();
	}

}
public class RightHairBuilder implements HairBuilder {

	@Override
	public Hair getHair() {
		return new RightHair();
	}

}
public class HairFactory {
	
	private HairBuilder hairBuilder;
	
	public HairFactory(HairBuilder hairBuilder) {
		this.hairBuilder = hairBuilder;
	}

	public void setHairBuilder(HairBuilder hairBuilder) {
		this.hairBuilder = hairBuilder;
	}

	public Hair getHair() {
		return hairBuilder.getHair();
	}
}
public class HairTest {

	public static void main(String[] args) {
//		HairBuilder builder = new LeftHairBuilder();
		HairBuilder builder = new RightHairBuilder();
		HairFactory factory = new HairFactory(builder);
		Hair hair = factory.getHair();
		hair.draw();
	}
}
这种做法的好处是无需再去修改工厂类,将工厂里面的创建对量逻辑根据不同的策略抽象出来,程序需要创建什么对象,只需网工厂中传入相应的builder即可。

二、工厂方法

在简单工厂模式中,系统使用工厂类生产所有产品实例,且该工厂类决定生产哪个类的实例,即工厂类负责所有的逻辑判断、实例创建等工作。

如果不想再工厂类中进行逻辑判断,程序可以为不同的产品类提供不同的工厂,不同的工厂类生产不同的产品,无需再工厂类中进行复杂的逻辑判断。这就有点类似于上面的简单工厂模式结合策略模式,不同的是前者只有一个工厂,后者需要有多个工厂。下面是工厂方法模式的代码。

/**
 * 工厂方法模式
 * 需要工厂生产的对象实例所实现的共同的接口
 * @author Administrator
 *
 */
public interface Person {

	public void drawPerson();
}
public class Man implements Person {

	@Override
	public void drawPerson() {
		System.out.println("---------------------draw a man--------------------");
	}

}
public class Women implements Person {

	@Override
	public void drawPerson() {
		System.out.println("--------------------draw a women---------------------");
	}

}
/**
 * 生产人的工厂
 * @author Administrator
 *
 */
public interface PersonFactory {
	//生产人
	public Person getPerson();
}
/**
 * 生产man的工厂
 * @author Administrator
 *
 */
public class ManFactory implements PersonFactory {

	@Override
	public Person getPerson() {
		return new Man();
	}

}
/**
 * 声场women的工厂
 * @author Administrator
 *
 */
public class WomenFactory implements PersonFactory {

	@Override
	public Person getPerson() {
		return new Women();
	}

}
/**
 * 客户端测试类
 * @author Administrator
 *
 */
public class PersonTest {

	public static void main(String[] args) {
//		PersonFactory factory = new ManFactory();
		PersonFactory factory = new WomenFactory();
		Person person = factory.getPerson();
		person.drawPerson();
	}
}

这种的典型的特点就是在客户端代码中根据不同的工厂生产其对应的产品,不必把复杂的逻辑都放在工厂类里面判断。这种实现有一个很明显的缺陷,就是客户端与工厂类进行了耦合。

三、抽象工厂

采用上面的工厂方法的设计架构,客户端代码成功与被调用对象的实现类分离,但带来了另一种耦合:客户端代码与不同的工厂类耦合。为了解决这种耦合的问题,考虑在增加一个工厂类,用来生成工厂实例,实现生产产品的工厂与客户端分离,这种设计方式被称为抽象工厂模式。下面是抽象工厂模式的代码
/**
 * 抽象工厂模式
 * 生产PersonFactory的工厂
 * @author Administrator
 *
 */
public class PersonFactoryFactory {

	public static PersonFactory  getPersonFactory(String type) {
		if(type.equalsIgnoreCase("man")) {
			return new ManFactory();
		} else {
			return new WomenFactory();
		}
	}
}
/**
 * 客户端测试类
 * @author Administrator
 *
 */
public class PersonTest {

	public static void main(String[] args) {
		PersonFactory factory = PersonFactoryFactory.getPersonFactory("man");
		Person person = factory.getPerson();
		person.drawPerson();
	}
}













一个例子穿插三种不同的工厂模式形态

1、简单工厂模式 工厂类根据提供给它的参数,返回的是几个产品中的一个类的实例。通常情况下,它返回的是一个公共的父类,在这个工厂类里面,父类的引用指向子类的对象 厂长生产杯子时先不让生产线知道我...
  • u013360022
  • u013360022
  • 2016年04月07日 21:59
  • 624

单例、多例模式&&工厂模式

单例、多例模式假设,老张开车去东北public class Car { public void run(){ System.out.println("冒着烟奔跑中car..........
  • hackerHL
  • hackerHL
  • 2017年02月22日 15:20
  • 820

单例模式,工厂模式,代理模式汇总

1.单例模式: 饿汉式 (可用) public class Demo{ private static Demo demo = new Demo(); private Demo()...
  • rusbme
  • rusbme
  • 2016年05月03日 16:17
  • 3308

工厂模式及在项目中的应用

工厂模式分为简单工厂、工厂方法模式和抽象工厂模式。简单工厂顾名思义是最简单的,从一个工厂获取所需的产品类似于factory.getProduct1();或factory.getProduct2(),最...
  • empyan
  • empyan
  • 2017年02月06日 21:20
  • 2515

关于工厂模式的作用。为什么要用工厂模式?

关于工厂模式的作用。为什么要用工厂模式?
  • kocscs123
  • kocscs123
  • 2016年11月20日 19:56
  • 1063

Android设计模式之工厂模式 Factory

一.概述 平时做项目跟使用第三方类库的时候经常会用到工厂模式.什么是工厂模式,简单来说就是他的字面意思.给外部批量提供相同或者不同的产品,而外部不需要关心工厂是如何创建一个复杂产品的过...
  • l2show
  • l2show
  • 2015年08月23日 16:25
  • 20439

Spring 实现两种设计模式:工厂模式和单态模式

本文摘自:李刚 著 《轻量级 Java EE企业应用实战 Struts2+Spring+hibernate整合开发》                   在Spring 中大量使用的以下两种设...
  • Titilover
  • Titilover
  • 2011年08月31日 13:05
  • 26631

工厂模式详解

工厂模式详解java实现
  • huruzun
  • huruzun
  • 2014年05月23日 17:41
  • 1591

iOS 设计模式之工厂模式

工厂模式我的理解是:他就是为了创建对象的 创建对象的时候,我们一般是alloc一个对象,如果需要创建100个这样的对象,如果是在一个for循环中还好说,直接一句alloc就行了,但是事实并不那么如意,...
  • xiazailushang
  • xiazailushang
  • 2014年02月10日 18:05
  • 35265

面试问题,多态,工厂模式

具体说,多态就是基类的指针在调用虚函数成员的时候,运行时系统会根据指针实际指向的对象调用恰当的成员函数。 当一个方法在不同的环境中有不同的实现时,可以使用多态,抽象出一个接口,子类有不同的实现。 ...
  • digaoyang
  • digaoyang
  • 2014年12月03日 10:13
  • 1245
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:工厂模式
举报原因:
原因补充:

(最多只允许输入30个字)