设计模式-工厂模式 Java示例

Posted Ruffian-痞子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式-工厂模式 Java示例相关的知识,希望对你有一定的参考价值。

工厂模式是创建型的设计模式之一,常被用于创建新对象

开发中常用 new 关键字创建一个对象,对象越来越多的时候,我们希望通过一个工厂来管理如何生产这些对象,于是工厂模式诞生了

先理解:需要生成的对象叫做 产品 ,生成对象的地方叫做 工厂

ok,直接看例子(网上看到有人用面条讲解,觉得很不错,贴合实际生活)

1 简单工厂模式

面店卖面条,这是一个很常见场景

抽象一个面条基类,也就是 产品 抽象类

    public abstract class Noodle 
        /**
         * 描述
         */
        public abstract void desc();
    

有一种拌面

    public class BanNoodle extends Noodle 

        @Override
        public void desc() 
            System.out.println("拌面");
        
    

有一种泡面

    public class PaoNoodle extends Noodle 
        @Override
        public void desc() 
            System.out.println("泡面");
        
    

现在有一家面馆,只卖这两种面(简单工厂)别的没有

    public class NoodleFactory 

        public static final int TYPE_PAO = 1, TYPE_BAN = 2;

        public Noodle createNoodle(int type) 
            Noodle noodle = null;
            if (type == 1) 
                noodle = new PaoNoodle();
             else if (type == 2) 
                noodle = new BanNoodle();
             else 
                System.out.println("没有你要的面");
            
            return noodle;
        

    

这是一家很简单的面馆,只有这两种面条,你只能选一种,别的没有。好吧,那就点一个拌面

    public class Test 

        public static void main(String args[]) 
            NoodleFactory factory = new NoodleFactory();
            Noodle noodle = factory.createNoodle(NoodleFactory.TYPE_BAN);
            noodle.desc();
        

    

输出:

拌面

NoodleFactory 就是我们的工厂。 createNoodle 方法创建产品并返回,如果此时 createNoodle 是静态方法,也可以成为 静态工厂

缺点

拓展性差,如果增加一种面条,就需要修改工厂的 createNoodle 里面的代码

2 简单工厂模式 (反射实现)

上面的简单工厂方式,一看就很low的样子,首先新增一种面条类型就要添加一个 if/switch 判断,再者 一个方法一长串的 if/else 一看就很低级。那么就用屌一点的写法 反射

只要我传一个对象指令进去,你直接返回该对象给我就行了,添加产品的时候也不用再修改代码

    public class NoodleFactory 

        public <T extends Noodle> T createNoodle(Class<T> cls) 
            T result = null;
            try 
                result = (T) Class.forName(cls.getName()).newInstance();
             catch (Exception e) 
                e.printStackTrace();
            
            return result;
        

    

诶~这个就很舒服了,只要传入 Class 就可以通过反射返回对应的对象,就算添加新的产品(面条)也不用修改 createNoodle 方法了。

那行啦,这种反射的方式完美解决一切,收工睡觉。

秋朵嘛得~~

Class.forName(cls.getName()).newInstance() 调用的是无参构造函数生成对象,对于复杂参数构造方法,他就无能为力啦

缺点

对象不支持复杂参数构造

3 多方法工厂模式

对于第1、2中模式,存在缺点:不同的产品需要不同额外参数的时候 不支持。

多方法工厂模式为不同产品提供不同的生产方法,使用时,需要哪个产品就调用对应的方法生产,方便,容错率高(不再有if匹配不到返回空的情况)

工厂代码如下:

    public class MultiFactory 

        /**
         * 生产拌面
         * 传递参数:口味
         */
        public Noodle createBanNoodle(String flavor) 
            return new BanNoodle(flavor);
        

        /**
         * 生产泡面
         */
        public Noodle createPaoNoodle() 
            return new PaoNoodle();
        

    

现在为拌面产品添加一个新的构造方法,接受一个参数(口味)

    public class BanNoodle extends Noodle 

        private String mFlavor;

        public BanNoodle(String flavor) 
            mFlavor = flavor;
        

        @Override
        public void desc() 
            System.out.println("拌面" + mFlavor);
        
    

现在,点一份麻辣口味的拌面,点一份普通泡面

    public class Test 

        public static void main(String args[]) 
            MultiFactory factory = new MultiFactory();
            Noodle banNoodle = factory.createBanNoodle("麻辣");
            banNoodle.desc();
            Noodle paoNoodle = factory.createPaoNoodle();
            paoNoodle.desc();
        

    

输出结果

拌面麻辣
泡面

这就是多方法工厂模式,工厂类为不同产品提供不同方法,准确,方便的创建并返回产品对象

4 普通工厂模式

普通工厂模式是对简单工厂模式的升级,将简单工厂的工厂类划分为两层:抽象工厂层 + 具体工厂子类实现层

先看 抽象工厂层

    public abstract class NoodleFactory 
        public abstract Noodle createNoodle();
    

拌面工厂

    public class BanNoodleFactory extends NoodleFactory 
        @Override
        public Noodle createNoodle() 
            return new BanNoodle();
        
    

泡面工厂

    public class PaoNoodleFactory extends NoodleFactory 
        @Override
        public Noodle createNoodle() 
            return new PaoNoodle();
        
    

使用:

    public static void main(String args[]) 
        NoodleFactory noodleFactory = new BanNoodleFactory();
        Noodle noodle = noodleFactory.createNoodle();
        noodle.desc();
    

通过简单示例代码可以看出:
1.普通工厂,不仅产品要抽象出来,连工厂都抽象出来了
2.在简单工厂中,直接在工厂类实现的产品创建,现在延迟到了工厂子类中实现

特点:
当新增一种产品时,除了新增产品相关的子类。还需要新增创建产品的工厂子类。比如新增:汤面
汤面(Noodle产品子类)

    public class TangNoodle extends Noodle
        @Override
        public void desc() 
            System.out.println("汤面");
        
    

生产汤面工厂(工厂子类)

    public class TangNoodleFactory extends NoodleFactory 
        @Override
        public Noodle createNoodle() 
            return new TangNoodle();
        
       

5 抽象工厂模式

以上所举例子都是单产品情况,也就是工厂只生产单一产品(面条),接下来了解一下多产品(面条,饮料,小菜…)

这时候,饭店是工厂生产系列产品(面条,饮料),而子类工厂可以理解为不同地区的分店

在卖面条的基础上添加一类新的产品,饮料
饮料抽象类

    public abstract class Drink 
        /**
         * 描述
         */
        public abstract void desc();
    

可乐

    public class ColaDrink extends Drink 
        @Override
        public void desc() 
            System.out.println("可乐");
        
    

牛奶

    public class MilkDrink extends Drink 
        @Override
        public void desc() 
            System.out.println("牛奶");
        
    

接下来就是抽象工厂类。这里的定义:饭店不仅是卖面条了,还有饮料

    public abstract class FoodFactory 
        /**
         * 生产面条
         */
        public abstract Noodle createNoodle();

        /**
         * 生产饮料
         */
        public abstract Drink createDrink();
    

具体工厂子类,表示某一个分店。如:深圳分店

    public class SZFoodFactory extends FoodFactory 

        @Override
        public Noodle createNoodle() 
            return new BanNoodle();
        

        @Override
        public Drink createDrink() 
            return new ColaDrink();
        
    

广州分店

    public class GZFoodFactory extends FoodFactory 
        @Override
        public Noodle createNoodle() 
            return new PaoNoodle();
        

        @Override
        public Drink createDrink() 
            return new MilkDrink();
        
    

使用(现在来到深圳分店,要了一份拌面,一杯可乐)

    public static void main(String args[]) 
        FoodFactory foodFactory = new SZFoodFactory();
        foodFactory.createNoodle().desc();
        foodFactory.createDrink().desc();
    

输出

拌面
可乐

抽象工厂模式,定义了工厂生产的产品系列(或者产品族),通过抽象基类,确定了创建的产品类型,相当于简单工厂和多方法工厂的结合(当然不是指代码上,而是思想上)

所谓存在即合理,我们通过学习设计模式的思想,在开发中恰当的使用特定的设计模式,能够合理的解决特定的问题,但切勿为了设计模式而强行使用。

以上是关于设计模式-工厂模式 Java示例的主要内容,如果未能解决你的问题,请参考以下文章

java 三种工厂模式

设计模式 工厂模式

工厂模式

Java 工厂方法模式的简单示例

Java工厂模式之总有你想不到的知识

JDK中应用单例模式简单工厂模式的示例