工厂模式详解

栏目: 后端 · 发布时间: 5年前

内容简介:即静态工厂模式1.将对象的创建和使用分开;

六大设计原则

工厂模式详解

简单工厂模式

即静态工厂模式

1.将对象的创建和使用分开;

2.将生产过程集中,便于集中管理;

3.当需要创建的对象类有变动时,就不用在所有new 的地方修改了,直接修改工厂类即可;

/**
 * 简单工厂模式 --- 静态工厂模式
 */
public class StaticFactory {
    public static final int TYPE_APPLE = 1;//苹果
    public static final int TYPE_ORANGE = 2;//桔子
    public static final int TYPE_BANANA = 3;//香蕉

    public static Fruit getFruit(int type){
        if(TYPE_APPLE == type){
            return new Apple();
        } else if(TYPE_ORANGE == type){
           return new Orange("Peter",80);
        } else if(TYPE_BANANA == type){
            return new Banana();
        }
        return null;
    }

    /**
     * 多方法工厂
     * @return
     */
    public static Fruit getFruitApple(){
        return new Apple();
    }

    public static Fruit getFruitOrange(){
        return new Orange("Peter",80);
    }

    public static Fruit getFruitBanana(){
        return new Banana();
    }


}

总的来说,简单工厂模式就是 用一个专业类(工厂类)来负责一种产品(水果类)的对象创建

简单工厂模式不属于23种设计模式,是工厂模式的基础.

思考?若工厂生产的产品越来越多,静态工厂不断修改,方法扩展极为庞大,产品品种扩展不优雅.

  • 1.不符合单一职责原则:一个类负责了各类水果的创建.
  • 2.不符合开闭原则:扩展品种时,需要修改已有代码,修改工厂类.

工厂方法模式

为了解决静态工厂的问题,我们采用工厂方法模式

  • 1.将静态工厂打散,每一个水果品类,对应一个水果品类工厂来生产。
  • 2.当需要扩展水果品类时,对应扩展一个水果品种的工厂即可。

将工厂类抽象出一个接口,对象的创建方法延迟到工厂子类去实现.

/**
 * 工厂方法接口
 */
public interface FruitFactory {
    public Fruit getFruit();//摘水果指令
}

/**
 * 橘子工厂子类
 */
public class OrangeFactory implements FruitFactory{
    public Fruit getFruit(){
        return new Orange("Peter",80);
    }
}


 /**
 * 香蕉工厂子类
 */
public class BananaFactory implements FruitFactory{
    public Fruit getFruit(){
        return new Banana();
    }
}
/**
 * 苹果工厂子类
 */
public class AppleFactory implements FruitFactory{
    public Fruit getFruit(){
        return new Apple();
    }
}

 /**
 * 水果获取测试
 *
 */
public class FruitTest {

    private static FruitFactory fruitFactory;

    public static void main(String[] args) {
        getFruit();
    }

    /**
     * 获得水果
     */
    public static void getFruit(){
        //初始化苹果工厂
        fruitFactory = new AppleFactory();
        Fruit fruit = fruitFactory.getFruit();
        fruit.getFruit();

        //初始化香蕉工厂
        fruitFactory = new BananaFactory ();
        Fruit bananafruit = fruitFactory.getFruit();
        bananafruit.getFruit();
        //想要获取什么水果就实例化哪个工厂

    }
}

通过工厂方法模式,解决了单一职责和开闭原则问题。

需要具体的产品则初始化对应的工厂,在spring中经常是配置在配置文件中,

//然后注入进去,面向接口编程我们注入的是接口实现类在配置里
@Autowired
private FruitFactory fruitFactory;

为什么使用抽象工厂模式

业务慢慢发展,现在水果店品种增加,那我们按着工厂方法模式新增其他工厂实现类。

现在除了卖水果的服务还要提供额外服务,比如要包装好,同样的我们就新建一个包装工厂接口如下BagFactory负责打包。

/**
 * 工厂方法模式
 */
public interface BagFactory {
    public Bag getBag();//打包指令
}
/**
 * 负责香蕉的打包
 */
public class BananaBagFactory implements BagFactory{
    public Bag getBag(){
        return new BananaBag();
    }
}
/**
 * 负责苹果的打包
 */
public class AppleBagFactory implements BagFactory{
    public Bag getBag(){
        return new AppleBag();
    }
}

一个水果店的动作,就有从工厂获取水果,然后从工厂获取打包服务,如下:

/**
 * 水果店测试
 * Created by Peter on 10/8 008.
 */
public class FruitStoreTest {

    private static FruitFactory fruitFactory;
    private static BagFactory bagFactory;

    public static void main(String[] args) {
        pack();
    }

    /**
     * 邮寄打包
     */
    public static void pack(){
        //初始化苹果工厂
        fruitFactory = new AppleFactory();//猎取工厂不对应
        Fruit fruit = fruitFactory.getFruit();
        fruit.draw();

        //初始化苹果包装工厂
        bagFactory = new BananaBagFactory();
        Bag bag = bagFactory.getBag();

        bag.pack();

        //....邮寄业务
    }

产品类图如下:

工厂模式详解

同样的,要是再加一个邮寄业务,我们也是同样的新增一个邮寄工厂。

问题?在实际写代码的时候是否会发生这种问题: 即猎取工厂不对应

  • 1.初始化苹果工厂获取苹果
  • 2.初始化香蕉工厂来做包装业务
  • 3.初始化别的邮寄工厂来做邮寄服务

抽象工厂模式

针对上面的问题就要用到我们的抽象工厂模式了。

抽象工厂模式:当一个类别的产品还有多个系列区分时,为了按系列生产商品,使用抽象工厂区分。

比如不同水果有不同包装规格,客户下单时,自动配出包装,

  • --生产苹果,配置纸箱包装
  • --生产香蕉时,配置竹萝包装

PS:保证客户端只使用同一个产品族中的对象(如下代码的AppleFactory,BananaFactory)。

/**
 * 抽象水果工厂
 */
public abstract class AbstractFactory {

    public abstract  Fruit getFruit();

    public abstract Bag getBag();

}


/**
 * 水果工厂
 */
public class AppleFactory extends AbstractFactory{

    @Override
    public Fruit getFruit() {
        return new Apple();
    }

    @Override
    public Bag getBag() {
        return new AppleBag();
    }
}

/**
 * 水果工厂
 */
public class BananaFactory extends AbstractFactory{

    @Override
    public Fruit getFruit() {
        return new Banana();
    }

    @Override
    public Bag getBag() {
        return new BananaBag();
    }
}

/**
 * 抽象工厂模式测试
 * 按订单发送货品给客户
 * Created by Peter on 10/8 008.
 */
public class OrderSendClient {
    public static void main(String[] args){
        sendFruit();
    }

    public static void sendFruit(){
        //初始化工厂
        AbstractFactory factory = new AppleFactory();//spring使用注入方式

        //得到水果
        Fruit fruit = factory.getFruit();
        fruit.draw();
        //得到包装
        Bag bag = factory.getBag();
        bag.pack();
        //以下物流运输业务。。。。

    }

}

抽象工厂模式类图:

工厂模式详解

以上代码缺少一些实体类接口类,Fruit,Apple,Banana,Bag,AppleBag等等,主要学习这个设计思路


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

CLR via C#

CLR via C#

(美)Jeffrey Richter / 周靖 / 清华大学出版社 / 2010-9 / 99.00元

本书针对CLR和.NET Framework 4.0进行深入、全面的探讨,并结合实例介绍了如何利用它们进行设计、开发和调试。全书5部分29章。第Ⅰ部分介绍CLR基础,第Ⅱ部分解释如何设计类型,第Ⅲ部分介绍基本类型,第Ⅳ部分以实用特性为主题,第Ⅴ部分花大量篇幅重点介绍线程处理。 通过本书的阅读,读者可以掌握CLR和.NET Framework的精髓,轻松、高效地创建高性能应用程序。一起来看看 《CLR via C#》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试