例子一
package com.test.factorymodel;
/**
* 工厂方法:一抽象产品类派生出多个具体产品类;一抽象工厂类派生出多个具体工厂类;每个具体工厂类只能创建一个具体产品类的实例。
即定义一个创建对象的接口(即抽象工厂类),让其子类(具体工厂类)决定实例化哪一个类(具体产品类)。“一对一”的关系。
在以下情况下,适用于工厂方法模式:
(1) 当一个类不知道它所必须创建的对象的类的时候。
(2) 当一个类希望由它的子类来指定它所创建的对象的时候。
(3) 当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。
* @author Administrator
*
*/
public class FactoryMethod {
// 抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。
public static abstract class Phone {
public Phone() {
// TODO Auto-generated constructor stub
}
}
// 具体产品角色:工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现。
public static class iPhone extends Phone {
public iPhone() {
// TODO Auto-generated constructor stub
System.out.println("iPhone");
}
}
// 具体产品角色:工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现。
public static class AndroidPhone extends Phone {
public AndroidPhone() {
// TODO Auto-generated constructor stub
System.out.println("AndroidPhone");
}
}
// 抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。
public interface IFactory {
Phone createPhone();
}
// 具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。
public static class iPhoneFactory implements IFactory {
@Override
public Phone createPhone() {
// TODO Auto-generated method stub
return new iPhone();
}
}
// 具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。
public static class AndroidPhoneFactory implements IFactory {
@Override
public Phone createPhone() {
// TODO Auto-generated method stub
return new AndroidPhone();
}
}
public static class FactoryMethod_Customer {
public static void main(String[] args) {
iPhoneFactory factoryiPhone = new iPhoneFactory();
Phone iPhone = factoryiPhone.createPhone();
AndroidPhoneFactory factoryAndroidPhone = new AndroidPhoneFactory();
Phone androidPhone = factoryAndroidPhone.createPhone();
}
}
}
例子二
interface Human {
public void Talk();
public void Walk();
}
class Boy implements Human{
@Override
public void Talk() {
System.out.println("Boy is talking...");
}
@Override
public void Walk() {
System.out.println("Boy is walking...");
}
}
class Girl implements Human{
@Override
public void Talk() {
System.out.println("Girl is talking...");
}
@Override
public void Walk() {
System.out.println("Girl is walking...");
}
}
public class HumanFactory {
public static Human createHuman(String m){
Human p = null;
if(m == "boy"){
p = new Boy();
}else if(m == "girl"){
p = new Girl();
}
return p;
}
}
工厂模式:
首先需要说一下工厂模式。工厂模式根据抽象程度的不同分为三种:简单工厂模式(也叫静态工厂模式)、本文所讲述的工厂方法模式、以及抽象工厂模式。工厂模式是编程中经常用到的一种模式。它的主要优点有:
可以使代码结构清晰,有效地封装变化。在编程中,产品类的实例化有时候是比较复杂和多变的,通过工厂模式,将产品的实例化封装起来,使得调用者根本无需关心产品的实例化过程,只需依赖工厂即可得到自己想要的产品。
对调用者屏蔽具体的产品类。如果使用工厂模式,调用者只关心产品的接口就可以了,至于具体的实现,调用者根本无需关心。即使变更了具体的实现,对调用者来说没有任何影响。
降低耦合度。产品类的实例化通常来说是很复杂的,它需要依赖很多的类,而这些类对于调用者来说根本无需知道,如果使用了工厂方法,我们需要做的仅仅是实例化好产品类,然后交给调用者使用。对调用者来说,产品所依赖的类都是透明的。
工厂方法模式:
通过工厂方法模式的类图可以看到,工厂方法模式有四个要素:
工厂接口。工厂接口是工厂方法模式的核心,与调用者直接交互用来提供产品。在实际编程中,有时候也会使用一个抽象类来作为与调用者交互的接口,其本质上是一样的。
工厂实现。在编程中,工厂实现决定如何实例化产品,是实现扩展的途径,需要有多少种产品,就需要有多少个具体的工厂实现。
产品接口。产品接口的主要目的是定义产品的规范,所有的产品实现都必须遵循产品接口定义的规范。产品接口是调用者最为关心的,产品接口定义的优劣直接决定了调用者代码的稳定性。同样,产品接口也可以用抽象类来代替,但要注意最好不要违反里氏替换原则。
产品实现。实现产品接口的具体类,决定了产品在客户端中的具体行为。
前文提到的简单工厂模式跟工厂方法模式极为相似,区别是:简单工厂只有三个要素,他没有工厂接口,并且得到产品的方法一般是静态的。因为没有工厂接口,所以在工厂实现的扩展性方面稍弱,可以算所工厂方法模式的简化版,关于简单工厂模式,在此一笔带过。
适用场景:
不管是简单工厂模式,工厂方法模式还是抽象工厂模式,他们具有类似的特性,所以他们的适用场景也是类似的。
首先,作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要通过new就可以完成创建的对象,无需使用工厂模式。如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度。
其次,工厂模式是一种典型的解耦模式,迪米特法则在工厂模式中表现的尤为明显。假如调用者自己组装产品需要增加依赖关系时,可以考虑使用工厂模式。将会大大降低对象之间的耦合度。
再次,由于工厂模式是依靠抽象架构的,它把实例化产品的任务交由实现类完成,扩展性比较好。也就是说,当需要系统有比较好的扩展性时,可以考虑工厂模式,不同的产品用不同的实现工厂来组装。
===================================
补充例子:
1.HairInterface
package com.test.factorymodel.two4factorymethod;
public interface HairInterface {
public void colorHair();
}
2.RedHair
package com.test.factorymodel.two4factorymethod;
public class RedHair implements HairInterface{
@Override
public void colorHair() {
// TODO Auto-generated method stub
System.out.println("染成红色头发");
}
}
3.YellowHair
package com.test.factorymodel.two4factorymethod;
public class YellowHair implements HairInterface {
@Override
public void colorHair() {
// TODO Auto-generated method stub
System.out.println("染成黄色头发");
}
}
4.HairFactory
package com.test.factorymodel.two4factorymethod;
import java.util.Map;
public class HairFactory {
/**
* 根据类型来创建对象
*
* @param key
* @return
*/
public HairInterface getHair(String key) {
if ("red".equals(key)) {
return new RedHair();
} else if ("yellow".equals(key)) {
return new YellowHair();
}
return null;
}
/**
* 根据类的名称来生产对象
* @param className
* @return
*/
public HairInterface getHairByClass(String className){
try {
HairInterface hair = (HairInterface) Class.forName(className).newInstance();
return hair;
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
/**
* 根据类的名称来生产对象
* @param className
* @return
*/
public HairInterface getHairByClassKey(String key){
try {
Map<String, String> map = new PropertiesReader().getProperties();
HairInterface hair = (HairInterface) Class.forName(map.get(key)).newInstance();
return hair;
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
6.PropertiesReader
package com.test.factorymodel.two4factorymethod;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
/**
* properties文件的读取工具
* @author Administrator
*
*/
public class PropertiesReader {
public Map<String, String> getProperties() {
Properties props = new Properties();
Map<String, String> map = new HashMap<String, String>();
try {
InputStream in = getClass().getResourceAsStream("type.properties");
props.load(in);
Enumeration en = props.propertyNames();
while (en.hasMoreElements()) {
String key = (String) en.nextElement();
String property = props.getProperty(key);
map.put(key, property);
// System.out.println(key + " " + property);
}
} catch (Exception e) {
e.printStackTrace();
}
return map;
}
}
7.type.properties
red=com.test.factorymodel.two4factorymethod.RedHair
yellow=com.test.factorymodel.two4factorymethod.YellowHair
8.Test
package com.test.factorymodel.two4factorymethod;
public class Test {
public static void main(String[] args) {
//原始的
HairInterface red = new RedHair();
red.colorHair();
//工厂
HairFactory factory = new HairFactory();
HairInterface yellow = factory.getHair("yellow");
yellow.colorHair();
HairInterface red2 =
factory.getHairByClass("com.test.factorymodel.two4factorymethod.RedHair");
red2.colorHair();
HairInterface hair = factory.getHairByClassKey("yellow");
hair.colorHair();
}
}
9.结果
染成红色头发
染成黄色头发
染成红色头发
染成黄色头发