工厂模式属于创建型设计模式,它提供了一种创建对象的最佳方式。
1.简单工厂设计模式
先定义个接口:
public interface Milk {
/**
* 获取一个标准产品
* @return
*/
public String getName();
}
再定义接口的实现类1:
public class Mengniu implements Milk {
@Override
public String getName() {
return "蒙牛";
}
}
定义接口的实现类2:
public class Sanlu implements Milk{
@Override
public String getName() {
return "三鹿";
}
}
定义接口的实现类3:
public class Telunsu implements Milk {
@Override
public String getName() {
return "特仑苏";
}
}
定义接口实现类4:
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) {
//这个new的过程实际上一个比较复杂的过程
//有人民币及不需要自己new了
// System.out.println(new Telunsu().getName());
//小作坊式的生产模式
//用户本身不再关心生产的过程,而只需要关心这个结果
//假如:特仑苏、伊利、蒙牛
//成分配比都是不一样的
SimpleFactory factory = new SimpleFactory();
//把用户的需求告诉工厂
//创建产品的过程隐藏了,对于用户而且完全不清楚是怎么产生的
System.out.println(factory.getMilk("AAA"));
}
}
定义:一个创建产品对象的工厂接口,将实际创建工作推迟到子类工厂当中。
问题描述:简单工厂模式中,只要添加新的产品类,就得去修改工厂类,这样做势必违反了开闭原则。
解决方案:新增抽象工厂类,让抽象产品对应抽象工厂,让具体产品对应具体工厂,实际的创建工作推迟到子类工厂中去做。
2.创建实例工厂
定义工厂实现类1:
public class MengniuFactory implements Factory {
@Override
public Milk getMilk() {
return new Mengniu();
}
}
定义工厂实现类2:
public class SanluFactory implements Factory {
@Override
public Milk getMilk() {
return new Sanlu();
}
}
定义工厂实现类3:
/**
* 事情变得越来越专业
*
*/
public class TelunsuFactory implements Factory {
@Override
public Milk getMilk() {
return new Telunsu();
}
}
定义工厂实现类4:
public class YiliFactory implements Factory {
@Override
public Milk getMilk() {
return new Yili();
}
}
实现工厂模式:
/**
* 工厂模型
*
*/
public interface Factory {
//工厂必然具有生产产品技能,统一的产品出口
Milk getMilk();
}
测试实例工厂模式:
public class FactoryTest {
public static void main(String[] args) {
//System.out.println(new Factory().getMilk(););
//货比三家
//不知道谁好谁好谁坏
//配置,可能会配置错
Factory factory = new SanluFactory();
System.out.println(factory.getMilk());
}
分工明确,每种牛奶都有自己的生产流程和工序,用户只有选择权,没有决定权,内部细节对用户隐藏,扩展时候只需要扩展就好了,不必修改工厂类
3.抽象工厂
优点:
1、抽象工厂模式隔离了具体类的生产,使得客户并不需要知道什么被创建。
2、当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
3、增加新的具体工厂和产品族很方便,无须修改已有系统,符合“开闭原则”。
缺点:
增加新的产品等级结构很复杂,需要修改抽象工厂和所有的具体工厂类。
1.抽象工厂类:
/**
*
* 抽象工厂是用户的主入口
* 在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());
}
}
扩展时候,需要修改抽象工厂和具体的类,违背了“开闭原则”