浅谈设计模式之工厂模式

今天我们来看下创建型设计模式里面的工厂模式,工厂模式实现其实有好几种:

  • 简单工厂
  • 工厂方法
  • 抽象工厂

这几种实现对应的场景都不太一样,我们一个个来看下。

简单工厂

我们首先看下平时需要创建类是怎么创建的,先排除Spring之类的框架帮助,如果我们要创建类一般是需要手动去new它,但是这种对于多个类创建或者复杂逻辑的类创建就会很麻烦,我们每次都需要去new一次,重复执行很多代码。相信聪明的你想到了,对于会重复用到的部分抽出来弄成一个方法,可以反复调用,而这个方法就是专门创建类的方法,这个类不是一个类,是同一种类型下面所有实现类都能创建,比如一个造笔的工厂,那它就可以创建所有的笔实例。

于是就有了下面的代码:

    public static void main(String[] args) throws Exception {

        Pen p = null;

        p = PenFactory.producePen("crayon");

    }
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\分割线\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

public class PenFactory {
    public static Pen producePen(String pen) throws Exception {
        if ("crayon".equals(pen)) {//蜡笔
            return new Crayon();
        } else if ("chalk".equals(pen)) {//粉笔
            return new Chalk();
        } else if ("marker".equals(pen)) {//水彩笔
            return new Marker();
        } else {
            throw new Exception("not support Pen");
        }

    }
}

我们有一个producePen的方法,可以根据传入的参数生产不同的笔。

但是我们渐渐发现,如果随着生产笔种类的增多,会越来越多的ifelse分支,是否可以优化下呢?当然,可以借助查表法(这也是策略模式的思想)将所有创建的实例放到一个map里面,然后根据key去拿。这时候根据map的value存值不一样就有了不同的实现,可以直接存实例,那么就是工厂的单例模式;如果想要原型模式,每次创建新的对象,可以在value里面存class,然后拿到class之后调用class.newInstance()方法动态创建实例。这块实现就和spring里面的singletonprototype很类似。

修改完的代码如下:

    public static void main(String[] args) throws Exception {
        Pen p = null;
        p = PenFactory.producePen("crayon");
    }


public class PenFactory {
    private final static Map<String, Pen> cache = new HashMap<>();
    {
        cache.put("crayon", new Crayon());
        cache.put("chalk", new Chalk());
        cache.put("marker", new Marker());
    }
    public static Pen producePen(String pen) throws Exception {
        Pen p = cache.get(pen);
        if (p == null) {
            throw new Exception("not support Pen");
        }
        return p;
    }
}

上面是单例的简单工厂,如果是原型的话工厂类写法如下:

public class PenFactory {
    private final static Map<String, Class<?>> cache = new HashMap<>();
    {
        cache.put("crayon", Crayon.class);
        cache.put("chalk", Chalk.class);
        cache.put("marker", Marker.class);
    }
    public static Pen producePen(String pen) throws Exception {
        Class<?> p = cache.get(pen);
        if (p == null) {
            throw new Exception("not support Pen");
        }
        return (Pen) p.newInstance();
    }
}
工厂方法

简单工厂有个很大的问题,如果创建实例的逻辑不是很简单的一个new语句,比如前面还有很一些数据转换,或者计算之类的,最后在创建对象,它就不太能支持了。

这时候就需要用到工厂方法,工厂方法实现是先定义一个接口,然后里面定义一个producePen方法,每个种类的笔去实现这个方法,然后再和上面的方法类似,用一个工厂的工厂去选择需要创建的工厂,最后调用producePen去创建。

这里的工厂的工厂其实就是简单工厂的Map,然后具体接口实现就是每个方法的创建,里面多繁琐的逻辑都可以自己去实现。

    public static void main(String[] args) throws Exception {
        Pen p = null;
        p = PenFactoryMap.getPenFactory("crayon").producePen();
    }
    
public interface IPenFactory {
    Pen producePen();
}

public class ChalkFactory implements IPenFactory {
    @Override
    public Pen producePen() {
        return new Chalk();
    }
}

public class CrayonFactory implements IPenFactory {
    @Override
    public Pen producePen() {
        return new Crayon();
    }
}
public class MarkerFactory implements IPenFactory {
    @Override
    public Pen producePen() {
        return new Marker();
    }
}
public class PenFactoryMap {
    private static final Map<String, IPenFactory> factoryMap = new HashMap<>();
    {
        factoryMap.put("crayon", new CrayonFactory());
        factoryMap.put("chalk", new ChalkFactory());
        factoryMap.put("marker", new MarkerFactory());
    }
    public static IPenFactory getPenFactory(String pen) throws Exception {
        IPenFactory factory = factoryMap.get(pen);
        if (factory == null) {
            throw new Exception("not support Pen");
        }
        return factory;
    }
}

简单工厂应付一些创建流程繁琐但是具体实现不多的类型创建。

抽象工厂

但我们试想一下,这会我们只有三个类型的笔,蜡笔,水彩笔,粉笔。但是我们工厂业务发展起来了,需要对这些产品做拓展,比如每个类型要细分出7种颜色的笔,那我们就需要创建21个类,而且后面如果有其他业务新建,比如钢笔啥的来了又要创建很多类,这样会造成类爆炸,不好维护。

所以我们需要对一些类别进行整合,如果是一个类型的创建方法可以放到一个类里面。这时候接口也需要做相应更改,代码如下:

public interface IPenFactory {
    Pen produceStandardPen();
    Pen produceRedPen();
    Pen produceBluePen();
}

public class ChalkFactory implements IPenFactory {
    @Override
    public Pen produceStandardPen() {
        return new Chalk();
    }
    @Override
    public Pen produceRedPen() {
        return new RedChalk();
    }
    @Override
    public Pen produceBluePen() {
        return new BlueChalk();
    }
}
public class CrayonFactory implements IPenFactory {

    @Override
    public Pen produceStandardPen() {
        return new Crayon();
    }

    @Override
    public Pen produceRedPen() {
        return new RedCrayon();
    }

    @Override
    public Pen produceBluePen() {
        return new BlueCrayon();
    }

}

这儿我偷个懒,只写了两种颜色,懒得建那些类了,知道意思就行。抽象工厂一般用于同一种业务类型底层种类特别多的场景。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值