工厂模式按照《Java与模式》中的提法分为三类:
1. 简单工厂模式(Simple Factory)
2. 工厂方法模式(Factory Method)
3. 抽象工厂模式(Abstract Factory)
l 简单工厂
简单工厂模式的工厂类一般是使用静态方法,通过接收的参数的不同来返回不同的对象实例。
不修改代码的话,是无法扩展的。
示例:计算器(实现+ - * /)的运算
l 工厂方法
工厂方法是针对每一种产品提供一个工厂类。通过不同的工厂实例来创建不同的产品实例。
在同一等级结构中,支持增加任意产品。
工厂方法模式:工厂父类(接口)负责定义产品对象的公共接口,而子类工厂则负责创建具体的产品对象。
目的:是为了把产品的实例化操作延迟到子类工厂中完成,通过工厂子类来决定究竟应该实例化哪一个产品具体对象。
工厂方法模式包含四个部分:
1.抽象产品:产品对象同一的基类,或者是同一的接口。
2.具体的产品:各个不同的实例对象类
3.抽象工厂:所有的子类工厂类的基类,或是同一的接口
4.具体的工厂子类:负责每个不同的产品对象的实际创建
示例:
1. 抽象的产品类:定义car 交通工具类下:
package factory.simple;
/** * 抽象产品角色交通工具接口 */ public interface Car {
/** * 上班函数 */ void gotowork();
} |
2. 定义实际的产品类,总共定义两个,bike 和bus 分别表示不同的交通工具类
package factory.simple;
/** * 具体产品角色,自行车 * */ public class Bike implements Car { @Override public void gotowork() { System.out.println("骑自行车去上班!"); }
}
package factory.simple;
public class Bus implements Car {
@Override public void gotowork() { System.out.println("坐公交车去上班!"); }
} |
3. 抽象的工厂接口定义如下:
package factory.factory;
import factory.simple.Car;
/** * @author lilin * */ public interface ICarFactory {
/** * 获取交通工具 * * @return */ Car getCar();
} |
4. 具体的工厂子类,分别为每个具体的产品类创建不同的工厂子类:
package factory.factory;
import factory.simple.Bike; import factory.simple.Car;
public class BikeFactory implements ICarFactory {
@Override public Car getCar() { return new Bike(); }
}
package factory.factory;
import factory.simple.Bus; import factory.simple.Car;
public class BusFactory implements ICarFactory {
@Override public Car getCar() { return new Bus(); }
} |
5. 测试类,来验证下不同的工厂能够产生不同的产品对象:测试类如下
/** * */ package factory.factory;
import org.testng.annotations.Test;
import factory.simple.Car;
public class TestFactory {
@Test public void test() { ICarFactory factory = null; // bike factory = new BikeFactory(); Car bike = factory.getCar(); bike.gotowork();
// bus factory = new BusFactory(); Car bus = factory.getCar(); bus.gotowork(); }
} |
l 抽象工厂
抽象工厂是应对产品族概念的。比如说,每个汽车公司可能要同时生产轿车,货车,客车,那么每一个工厂都要有创建轿车,货车和客车的方法。
应对产品族概念而生,增加新的产品线很容易,但是无法增加新的产品。
抽象工厂模式:提供一个创建一系列的相关的或者依赖的对象的接口,无需指定它们的具体实现类,具体的实践分别在子类工厂中产生。隔离了具体类的生产实现,使得替换具体的工厂实现类很容易。包含有以下模块:
1.抽象产品接口:定义产品的接口,公共的暴露方法。便于实际的产品类实现。
2.具体的产品类:包含实际产品的类的逻辑处理:
3.抽象工厂接口:定义产生系列对象的接口
4.具体的工厂实现:实现抽象的接口工厂,返回具体的产品类的实现。
示例:
1. 抽象的产品接口,定义了Car 和 IBreakFast
package factory.simple;
/** * 抽象产品角色 交通工具接口 * */ public interface Car {
/** * 上班函数 */ void gotowork();
}
package factory.abstractfactory;
public interface IBreakFast { /** * 吃早餐 */ void eat(); } |
2. 定义具体的产品类的实现
package factory.simple;
/** * 具体产品角色,自行车 * */ public class Bike implements Car { @Override public void gotowork() { System.out.println("骑自行车去上班!"); }
}
package factory.simple;
public class Bus implements Car {
@Override public void gotowork() { System.out.println("坐公交车去上班!"); }
}
package factory.abstractfactory;
public class Milk implements IBreakFast {
@Override public void eat() { System.out.println("喝牛奶!"); }
}
package factory.abstractfactory;
public class Orange implements IBreakFast {
@Override public void eat() { System.out.println("吃饺子!"); }
} |
3. 定义好抽象的工厂接口,一系列的获取实例的接口方法
package factory.abstractfactory;
import factory.simple.Car;
public interface IAbstractFactory {
/** * * @return */ Car getCar();
/** * */ IBreakFast getBreakFast();
} |
4. 定义具体的工厂生产类,具体的产品实例返回
package factory.abstractfactory;
import factory.simple.Bike; import factory.simple.Car;
public class LowPersonFactory implements IAbstractFactory {
@Override public Car getCar() { return new Bike(); }
@Override public IBreakFast getBreakFast() { return new Orange(); }
}
package factory.abstractfactory;
import factory.simple.Bus; import factory.simple.Car;
public class HighPersonFactory implements IAbstractFactory {
@Override public Car getCar() { return new Bus(); }
@Override public IBreakFast getBreakFast() { return new Milk(); } } |
5. 测试
package factory.abstractfactory;
import org.testng.annotations.Test;
import factory.simple.Car;
public class AbstractFactoryTest {
@Test public void test() { IAbstractFactory factory = new LowPersonFactory(); Car car = factory.getCar(); IBreakFast breakFast = factory.getBreakFast(); System.out.println("吃的早饭是:"); breakFast.eat(); System.out.println("上班交通工具是:"); car.gotowork();
IAbstractFactory factory2 = new HighPersonFactory(); car = factory2.getCar(); breakFast = factory2.getBreakFast(); System.out.println("吃的早饭是:"); breakFast.eat(); System.out.println("上班交通工具是:"); car.gotowork(); }
} |
这样使用过程城中,只要注入抽象的工厂接口,具体的产品的产生,会在实际的子类工厂类中产生,也可以随意的添加和修改实际子类工厂类,而不需要改变既有的代码设计
小结
★工厂模式中,重要的是工厂类,而不是产品类。产品类可以是多种形式,多层继承或者是单个类都是可以的。但要明确的,工厂模式的接口只会返回一种类型的实例,这是在设计产品类的时候需要注意的,最好是有父类或者共同实现的接口。
★使用工厂模式,返回的实例一定是工厂创建的,而不是从其他对象中获取的。
★工厂模式返回的实例可以不是新创建的,返回由工厂创建好的实例也是可以的。
区别
简单工厂:用来生产同一等级结构中的任意产品。(对于增加新的产品,无能为力)
工厂方法:用来生产同一等级结构中的固定产品。(支持增加任意产品)
抽象工厂:用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族)
以上三种工厂方法在等级结构和产品族这两个方向上的支持程度不同。所以要根据情况考虑应该使用哪种方法