工厂模式
- 一、工厂模式的作用
- 二、简单工厂模式
- 三、工厂方法模式
- 四、抽象工厂模式
- 五、总结
一、工厂模式的作用
- 原本我们是用new来创建新对象,而现在我们用一个工厂类来代替创建新对象的工作
- 实现创建者和调用者的分离,调用者与实现类解耦(当实现类发生改变时,调用者的代码不需要做任何改变)
二、简单工厂模式
- 也称静态工厂模式
- 比如我们要造汽车,可以造Tesla也可以造Vw,我们构建一个工厂类来负责汽车对象的创建
简单工厂模式结构:
//一个Car的接口
public interface Car {
public void name();
}
//Tesla实现类
public class Tesla implements Car{
@Override
public void name() {
System.out.println("Tesla");
}
}
//Vw实现类
public class Vw implements Car{
@Override
public void name() {
System.out.println("Vw");
}
}
//现在我们来建一个简单工厂来做创建对象的工作
public class CarFactory {
public static Car getCar(String car)
{
if(car.equals("vw"))
{
return new Vw();
}
else if(car.equals("tesla"))
{
return new Tesla();
}
return null;
}
}
//在Consumer类中通过调用工厂创建对象
public class Consumer {
public static void main(String[] args) {
Car vw = CarFactory.getCar("vw");
Car tesla = CarFactory.getCar("tesla");
}
}
简单工厂模式小结:
- 简单工厂模式的结构,代码,编程以及管理上的复杂度都较小
- 但每次增加一个新产品必须要修改原有代码
三、工厂方法模式
- 同样的Car接口,Vw,Tesla实现类
- 然而现在我们要为工厂也构建一个接口,并且为每一种产品构建一个工厂实现类
工厂方法模式结构:
//工厂接口
public interface CarFactory {
Car getCar();
}
//Tesla工厂实现类
public class TeslaFactory implements CarFactory{
@Override
public Car getCar() {
return new Tesla();
}
}
//Vw工厂实现类
public class VwFactory implements CarFactory {
@Override
public Car getCar() {
return new Vw();
}
}
//调用各自工厂实现类来创建对象
public class Consumer {
public static void main(String[] args) {
Car vw = new VwFactory().getCar();
Car tesla = new TeslaFactory().getCar();
}
}
工厂方法模式小结:
- 横向扩展,增加新产品不需要改动原有代码,但要新构建一个工厂实现类,代码量大大增加
- 当业务变得很复杂的时候,我们可能会需要很多的工厂接口与工厂实现类,此时工厂方法模式就不再适用
四、抽象工厂模式
- 抽象工厂是工厂的工厂
- 抽象工厂模式提供了创建一系列相关或相互依赖对象的接口,无需指定他们具体的类
抽象工厂模式结构:
- 我们有华为和小米两家公司,每个公司都有手机和路由器两个产品
- 华为的手机和路由器属于一个产品族;而小米的手机和路由器属于另一个产品族
- 同一个产品族的产品将由一个工厂来生产,因此华为的产品都由华为工厂来创建,小米的产品都由小米工厂来创建
- 而华为工厂和小米工厂都会去实现一个工厂接口,也就是我们所说的工厂的工厂
//手机接口
public interface IphoneProduct {
void start();
}
//路由器接口
public interface IRouterProduct {
void start();
}
//抽象产品工厂,工厂的工厂
public interface IProductFactory {
//生产手机
IphoneProduct iphoneProduct();
//生产路由器
IRouterProduct iRouterProduct();
}
//小米工厂
public class XiaomiFactory implements IProductFactory{
@Override
public IphoneProduct iphoneProduct() {
return new XiaomiPhone();
}
@Override
public IRouterProduct iRouterProduct() {
return new XiaomiRouter();
}
}
//华为工厂
public class HuaweiFactory implements IProductFactory{
@Override
public IphoneProduct iphoneProduct() {
return new HuaweiPhone();
}
@Override
public IRouterProduct iRouterProduct() {
return new HuaweiRouter();
}
}
//小米手机
public class XiaomiPhone implements IphoneProduct{
@Override
public void start() {
System.out.println("start xiaomi phone");
}
}
//小米路由器
public class XiaomiRouter implements IRouterProduct{
@Override
public void start() {
System.out.println("start xiaomi router");
}
}
//华为手机
public class HuaweiPhone implements IphoneProduct{
@Override
public void start() {
System.out.println("start huawei phone");
}
}
//华为路由器
public class HuaweiRouter implements IRouterProduct{
@Override
public void start() {
System.out.println("start huawei router");
}
}
public class Consumer {
public static void main(String[] args) {
//调用小米工厂创建小米手机对象,小米路由器对象
XiaomiFactory xiaomiFactory = new XiaomiFactory();
IphoneProduct xiaomiPhone = xiaomiFactory.iphoneProduct();
IRouterProduct xiaomiRouter = xiaomiFactory.iRouterProduct();
//调用华为工厂创建华为手机对象,华为路由器对象
HuaweiFactory huaweiFactory = new HuaweiFactory();
IphoneProduct huaweiPhone = huaweiFactory.iphoneProduct();
IRouterProduct huaweiRouter = huaweiFactory.iRouterProduct();
xiaomiPhone.start();
xiaomiRouter.start();
huaweiPhone.start();
huaweiRouter.start();
}
}
输出:
start xiaomi phone
start xiaomi router
start huawei phone
start huawei router
抽象工厂模式小结:
- 优点
- 具体产品在应用层的代码隔离,无需关心创建的细节,创建对象时只要调用相应的工厂即可
- 将一个系列的产品统一到一起创建
- 缺点
- 产品族中扩展新的产品困难
- 增加了系统抽象性和理解难度
五、总结
- 简单工厂模式:虽然某种程度上不符合设计原则,但实际使用最多
- 工厂方法模式:不修改已有类的前提下,通过增加新的工厂类实现扩展
- 抽象工厂模式:不可以增加产品,可以增加产品族