设计模式 Java

概述

工厂模式是Java中常用的设计模式,主要思想将Bean的初始化、创建等过程交由工厂处理。调用端无需关系bean的初始化及创建信息,只需了解Bean提供的API。

一、简单工厂模式

简单工厂模式(静态工厂模式 - StaticFactory)简单来说,工厂根据参数创建并返回不同bean的实例。

IBook接口:


package com.miselehe.pattern.factory.bean;

/**
 * 书籍 
 *
 */
public interface IBook {
	
	/**
	 * 获取书籍名称
	 * @return
	 */
	public String getBookName();
	
}


Book实现类:


package com.miselehe.pattern.factory.bean;

/**
 * Java 书籍
 *
 */
public class JavaBook implements IBook {

	public String getBookName() {
		// TODO Auto-generated method stub
		return "Java Book!";
	}
}


package com.miselehe.pattern.factory.bean;

/**
 * Javascript 书籍
 *
 */
public class JavascriptBook implements IBook {

	public String getBookName() {
		// TODO Auto-generated method stub
		return "Javascript Book!";
	}

}
package com.miselehe.pattern.factory.bean;

/**
 * .net 书籍
 *
 */
public class NetBook implements IBook {
	
	
	public String getBookName() {
		// TODO Auto-generated method stub
		return ".Net Book!";
	}

}



工厂:


package com.miselehe.pattern.factory.simple;

import com.miselehe.pattern.factory.bean.IBook;
import com.miselehe.pattern.factory.bean.JavaBook;
import com.miselehe.pattern.factory.bean.JavascriptBook;
import com.miselehe.pattern.factory.bean.NetBook;

/**
 * 简单工厂 (静态工厂)
 *
 */
public class SimpleFactory {
	
	/**
	 * 获取Bean
	 * @param bookFlag
	 * @return
	 */
	public IBook getBook(String bookFlag) {
		if ("java".equals(bookFlag)) {
			return new JavaBook();
		} else if ("javasciprt".equals(bookFlag)) {
			return new JavascriptBook();
		} else if (".net".equals(bookFlag)) {
			return new NetBook();
		} else {
			return null;
		}
	}
	
}



测试代码:


package com.miselehe.pattern.factory.simple;

/**
 * 简单工厂模式 使用
 * @author 
 *
 */
public class SimpleFactoryTest {

	public static void main(String[] args) {
		SimpleFactory simpleFactory = new SimpleFactory();
		
		System.out.println(simpleFactory.getBook("java").getBookName()); // Java Book!
		System.out.println(simpleFactory.getBook("javasciprt").getBookName()); // Javascript Book!
		System.out.println(simpleFactory.getBook(".net").getBookName()); // .Net Book!
	}
	
}

这种方式很少使用。在使用时,调用端需要了解不同Bean的标记,标记错误无法获取到想要的结果。再需要扩展Bean时,Factory需要也需要增加标记。


二、工厂方法模式

不同业务Bean的实例,由不同工厂创建。

工厂接口:


package com.miselehe.pattern.factory.method;

import com.miselehe.pattern.factory.bean.IBook;

/**
 * 工厂接口
 *
 */
public interface IFactory {
	/**
	 * 获取实例
	 */
	public IBook getBook();
}


工厂实现类:


package com.miselehe.pattern.factory.method;

import com.miselehe.pattern.factory.bean.IBook;
import com.miselehe.pattern.factory.bean.JavaBook;

/**
 * Java 书籍工厂
 *
 */
public class JavaBookFactory implements IFactory {
	
	public IBook getBook() {
		// TODO Auto-generated method stub
		return new JavaBook();
	}
}
package com.miselehe.pattern.factory.method;

import com.miselehe.pattern.factory.bean.IBook;
import com.miselehe.pattern.factory.bean.JavascriptBook;

/**
 * javascript 书籍工厂
 *
 */
public class JavascriptBookFactory implements IFactory {

	public IBook getBook() {
		// TODO Auto-generated method stub
		return new JavascriptBook();
	}

}
package com.miselehe.pattern.factory.method;

import com.miselehe.pattern.factory.bean.IBook;
import com.miselehe.pattern.factory.bean.NetBook;

/**
 * .net 书籍工厂
 *
 */
public class NetBookFactory implements IFactory {

	public IBook getBook() {
		// TODO Auto-generated method stub
		return new NetBook();
	}
}
调用测试:



package com.miselehe.pattern.factory.method;
/**
 * 工厂方法模式测试
 *
 */
public class MethodFactoryTest {
	public static void main(String[] args) {
		
		/**
		 * 通过不同工厂获取不容bean
		 */
		JavaBookFactory javaBookFactory = new JavaBookFactory();
		System.out.println(javaBookFactory.getBook().getBookName()); // Java Book!
		
		JavascriptBookFactory javascriptBookFactory = new JavascriptBookFactory();
		System.out.println(javascriptBookFactory.getBook().getBookName()); // Javascript Book!
		
		NetBookFactory netBookFactory = new NetBookFactory();
		System.out.println(netBookFactory.getBook().getBookName()); // .Net Book!
		
	}
}
这种模式和简单工厂相比较:



  1. 在调用时需要根据不同工厂来获取Bean,不再需要标记,相对使用标记来说避免了标记错误而造成的错误,程序更加健壮;
  2. 在需要扩展时,不但需要增加新的Bean,而且可能需要增加新的Factory,但是避免了修改其他Factory,符合开闭原则;


这种方式一般比较常见(搭配抽象工厂);

三、抽象工厂模式

创建抽象类工厂,

抽象类工厂:


package com.miselehe.pattern.factory.abstractf;

import com.miselehe.pattern.factory.bean.IBook;

/**
 * 抽象工厂
 *
 */
public abstract class AbstractBookFactory {
	
	/**
	 * 获得java书籍
	 * @return
	 */
	public abstract IBook getJavaBook();
	
	/**
	 * 获得javascript书籍
	 * @return
	 */
	public abstract IBook getJavascriptBook();
	
	/**
	 * 获得.net书籍
	 * @return
	 */
	public abstract IBook getNetBook();
	
}


实现类工厂:


package com.miselehe.pattern.factory.abstractf;

import com.miselehe.pattern.factory.bean.IBook;
import com.miselehe.pattern.factory.bean.JavaBook;
import com.miselehe.pattern.factory.bean.JavascriptBook;
import com.miselehe.pattern.factory.bean.NetBook;

/**
 * 工厂实现类
 * @author sdc
 *
 */
public class BookFactory extends AbstractBookFactory {

	@Override
	public IBook getJavaBook() {
		// TODO Auto-generated method stub
		return new JavaBook();
	}

	@Override
	public IBook getJavascriptBook() {
		// TODO Auto-generated method stub
		return new JavascriptBook();
	}

	@Override
	public IBook getNetBook() {
		// TODO Auto-generated method stub
		return new NetBook();
	}

}


调用测试:


package com.miselehe.pattern.factory.abstractf;

/**
 * 调用抽象工厂
 *
 */
public class AbstractFactoryTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		BookFactory bookFactory = new BookFactory();
		
		System.out.println(bookFactory.getJavaBook().getBookName()); // Java Book!
		System.out.println(bookFactory.getJavascriptBook().getBookName()); // Javascript Book!
		System.out.println(bookFactory.getNetBook().getBookName()); // .Net Book!
	}

}


比较:

相比于简单工厂,由标记参数转换为了具体的方法。在扩展时,如果增加业务Bean则静态工厂和工厂实现类都需要扩展。



在实际使用中,往往会将三种方式混合使用,比如抽象工厂实现类中,创建Bean部分,再由工厂方法模式实现等。



转载请指明出处!http://www.miselehe.com/article/view/19