工厂顾名思义就是创建产品,根据产品是具体产品还是具体工厂可分为简单工厂模式和工厂方法模式,根据工厂的抽象程度可分为工厂方法模式和抽象工厂模式。该模式用于封装和管理对象的创建,是一种创建型模式。本文从一个具体的例子逐步深入分析,来体会三种工厂模式的应用场景和利弊。
1、简单工厂模式(Factory)
应用场景:又叫做静态工厂方法(StaticFactory Method)模式,但不属于 23 种设计模式之一。简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类。
Spring 中的 BeanFactory 就是简单工厂模式的体现,根据传入一个唯一的标识来获得 Bean 对象,但是否是在传入参数后创建还是传入参数前创建这个要根据具体情况来定。
以一个具体的例子来简单简化下工厂模式。假如我现在想要一份牛奶,但是牛奶生产厂家可以有蒙牛、特仑苏、伊利等品牌可供我选择,然后我通过牛奶工厂获得一份指定品牌牛奶。说完这个例子下面我也会用代码来实现这个例子,给大家简单理解下工厂模式。
首先我们来创建一个牛奶生产工厂的接口,因为这里只要有生产牛奶就行,所以写一个的方法。
public interface Milk {
/**
* 获取一个标准产品
* @return
*/
public String getName();
}
接下来写三个实现类,分别是做蒙牛,特仑苏,伊利,用这三个实现类去实现Milk接口。
public class Mengniu implements Milk {
@Override
public String getName() {
return "蒙牛";
}
}
public class Telunsu implements Milk {
@Override
public String getName() {
return "特仑苏";
}
}
public class Yili implements Milk {
@Override
public String getName() {
return "伊利";
}
}
生产牛奶的工厂
public class SimpleFactory {
public Milk getMilk(String name){
if("特仑苏".equals(name)){
return new Telunsu();
}else if("伊利".equals(name)){
return new Yili();
}else if("蒙牛".equals(name)){
return new Mengniu();
}else {
System.out.println("不能生产您所需的产品");
return null;
}
}
}
测试类:
public class SimpleFactoryTest {
public static void main(String[] args) {
//假如:特仑苏、伊利、蒙牛
//成分配比都是不一样的
SimpleFactory factory = new SimpleFactory();
//把用户的需求告诉工厂
//创建产品的过程隐藏了,对于用户而且完全不清楚是怎么产生的
System.out.println(factory.getMilk("蒙牛").getName());
System.out.println(factory.getMilk("特仑苏").getName());
}
}
2. 工厂方法模式(Factory Method)
和简单工厂模式中工厂负责生产所有产品相比,工厂方法模式将生成具体产品的任务分发给具体的产品工厂,其UML类图如下:
定义了产品的生产接口,但不负责具体的产品,将生产任务交给不同的派生类工厂。这样不用通过指定类型来创建对象了。
接下来继续使用生产手机的例子来讲解该模式。
其中和产品相关的特仑苏、伊利、蒙牛类的定义不变。
下面是工厂类接口:
public interface Factory {
//工厂必然具有生产产品技能,统一的产品出口
Milk getMilk();
}
MengniuFactory 蒙牛生产工厂
public class MengniuFactory implements Factory {
@Override
public Milk getMilk() {
return new Mengniu();
}
}
TelunsuFactory特仑苏生产工厂
public class TelunsuFactory implements Factory {
@Override
public Milk getMilk() {
return new Telunsu();
}
YiliFactory 伊利生产工厂
public class YiliFactory implements Factory {
@Override
public Milk getMilk() {
return new Yili();
}
}
}
测试:
public class FactoryTest {
public static void main(String[] args) {
//货比三家
//不知道谁好谁好谁坏
//配置,可能会配置错
Factory factory = new MengniuFactory();
System.out.println(factory.getMilk());
Factory factory1 = new TelunsuFactory();
System.out.println(factory1.getMilk());
Factory factory2 = new TelunsuFactory();
System.out.println(factory2.getMilk());
}
}
3 抽象工厂模式
基本定义:
抽象工厂模式是所有形态的工厂模式中最为抽象和最其一般性的。抽象工厂模式可以向客户端提供一个接口,使得客户端在不必指定产品的具体类型的情况下,能够创建多个产品族的产品对象。
知道抽象类:
/**
*
* 抽象工厂是用户的主入口
* 在Spring中应用得最为广泛的一种设计模式
* 易于扩展
*/
public abstract class AbstractFactory {
//公共的逻辑
//方便于统一管理
/**
* 获得一个蒙牛品牌的牛奶
* @return
*/
public abstract Milk getMengniu();
/**
* 获得一个伊利品牌的牛奶
* @return
*/
public abstract Milk getYili();
/**
* 获得一个特仑苏品牌的牛奶
* @return
*/
public abstract Milk getTelunsu();
public abstract Milk getSanlu();
}
实现类:
public class MilkFactory extends AbstractFactory {
@Override
public Milk getMengniu() {return new Mengniu();}
@Override
public Milk getYili() { return new Yili();}
@Override
public Milk getTelunsu() { return new Telunsu();}
@Override
public Milk getSanlu() {return new Sanlu();}
}
测试类:
public class AbstractFactoryTest {
public static void main(String[] args) {
MilkFactory factory = new MilkFactory();
//对于用户而言,更加简单了
//用户只有选择的权利了,保证了程序的健壮性
System.out.println(factory.getSanlu());
}
}
模式中包含的角色及其职责
1.抽象工厂(Creator)角色
抽象工厂模式的核心,包含对多个产品结构的声明,任何工厂类都必须实现这个接口。
2.具体工厂( Concrete Creator)角色
具体工厂类是抽象工厂的一个实现,负责实例化某个产品族中的产品对象
3.抽象(Product)角色
抽象模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。
4.具体产品(Concrete Product)角色
抽象模式所创建的具体实例对象
总结:抽象工厂中方法对应产品结构,具体工厂对应产品族。