title: 设计模式之工厂模式
date: 2020-11-26 22:37:00
tags: java GOF 设计模式
在现实生活中我们都知道,原始社会自给自足(没有工厂)、农耕社会有了小作坊(简单工厂),工业革命后有了流水线工厂(工厂方法),现在产业链中有代工厂(抽象工厂)。我们项目的代码也是这样一步一步的迭代过来的。
一、简单工厂模式
简单工厂模式是指由一个工厂对象决定创建哪一种产品类的实例,但它不属于Gof的23种设计模式中的其中一种。简单工厂模式适合工厂类创建的对象较少的场景。根据传入的参数来创建对象,至于如何创建就不要关心了。我们还是通过蛋糕来举例。看一下代码
public interface ICake {
void makeCake();
}
public class CakeFactory {
public ICake makeCake(String name) {
if ("apple".equals(name)) {
return new AppleCake();
} else if ("strawberry".equals(name)) {
return new StrawberryCake();
} else {
return null;
}
}
}
public class AppleCake implements ICake{
@Override
public void makeCake() {
System.out.println("制作苹果味的蛋糕");
}
}
public class StrawberryCake implements ICake{
@Override
public void makeCake() {
System.out.println("制作草莓味的蛋糕");
}
}
以上就是一个简单的工厂模式了。但是呢,如果我们多弄几种蛋糕的话,就需要在去改CakeFactory类了。这无疑是很麻烦的。因此,我们可以优化一下,使用动态代理来进行创建实体类。优化代码如下
public class CakeFactory {
public ICake makeCake(Class<? extends ICake> clazz) {
try {
if (null != clazz) {
return clazz.newInstance();
}
} catch (Exception e){
e.printStackTrace();
}
return null;
}
public static void main(String[] args) {
CakeFactory cakeFactory = new CakeFactory();
ICake appleCake = cakeFactory.makeCake(AppleCake.class);
appleCake.makeCake();
// 输出结果:制作苹果味的蛋糕
}
}
这样子的话,我们就可以随便的添加蛋糕,而不需要去修改工厂类喽。我们可以发现简单工厂也是很实用的。
二、工厂模式
工厂方法模式是指定义一个创建对象的接口,但是让这个接口的实现类去绝对实例化哪个类,让类的实例化推迟到子类中进行,这样就只需要关心产品所需要的工厂,无需关系细节。就例如报社把订单交到印刷厂里,由每个不同的车间进行操作,印刷,裁纸,装订等不同的车间干不同的活,甚至是不同的小工厂,然而这不是报社需要操心的事。为了习惯,我还是按苹果味的蛋糕和草莓味的蛋糕来举例好吧。我们看如下代码:
public interface ICakeFactory {
ICake makeCake();
}
public class AppleCakeFactory implements ICakeFactory{
@Override
public ICake makeCake() {
return new AppleCake();
}
}
public class StrawberryCakeFactory implements ICakeFactory{
@Override
public ICake makeCake() {
return new StrawberryCake();
}
}
工厂方法模式适用于一下场景
- **创建对象需呀大量重复的代码**
- **客户端不依赖于产品类实例如何呗创建、如何实现等细节**
- **一个类通过其子类来指定创建哪个对象**
但也很明显哈,它也有一些缺点:
- **类的个数容易太多,增加复杂度**
- **增加了系统的抽象性和理解难度**
三、抽象工厂模式
抽象工厂呢,他是一个抽象的东西,为什么这么说呢,因为他的名字中有抽象两个字,哈哈。冷不冷。抽象工厂,我的理解呢就是世界上有那么多的蛋糕店,每个蛋糕店都做不一样品种的蛋糕,我们首先去选择哪个蛋糕店,然后在选择这个店里的那个蛋糕。好像有点绕吼。我们还是通过代码来进行理解吧。假如我们有Naomi蛋糕店和木子蛋糕店这两个店,这两个店都属于shmilylyp的,哈哈。每个店里面都卖奶油蛋糕,无糖蛋糕和馒头糕点等。看如下代码:
public interface IAppleCake {
void makeAppleCake();
}
public interface IStrawberryCake {
void makeStrawberryCake();
}
public interface ICakeFactory {
IAppleCake makeAppleCake();
IStrawberryCake makeStrawberryCake();
}
public class MuziStoreMakeAppleCake implements IAppleCake{
@Override
public void makeAppleCake() {
System.out.println("木子制作苹果蛋糕工厂");
}
}
public class MuziStoreMakeStrawberryCake implements IStrawberryCake{
@Override
public void makeStrawberryCake() {
System.out.println("木子制作草莓蛋糕工厂");
}
}
public class NaomiStoreMakeAppleCake implements IAppleCake{
@Override
public void makeAppleCake() {
System.out.println("naomi制作苹果蛋糕工厂");
}
}
public class NaomiStoreMakeStrawberryCake implements IStrawberryCake{
@Override
public void makeStrawberryCake() {
System.out.println("naomi制作草莓蛋糕工厂");
}
}
public class MuziStoreFactory implements ICakeFactory{
@Override
public IAppleCake makeAppleCake() {
return new MuziStoreMakeAppleCake();
}
@Override
public IStrawberryCake makeStrawberryCake() {
return new MuziStoreMakeStrawberryCake();
}
}
public class NaomiStoreFactory implements ICakeFactory{
@Override
public IAppleCake makeAppleCake() {
return new NaomiStoreMakeAppleCake();
}
@Override
public IStrawberryCake makeStrawberryCake() {
return new NaomiStoreMakeStrawberryCake();
}
}
public class Test {
public static void main(String[] args) {
NaomiStoreFactory naomiStoreFactory = new NaomiStoreFactory();
naomiStoreFactory.makeAppleCake().makeAppleCake();
naomiStoreFactory.makeStrawberryCake().makeStrawberryCake();
MuziStoreFactory muziStoreFactory = new MuziStoreFactory();
muziStoreFactory.makeAppleCake().makeAppleCake();
muziStoreFactory.makeStrawberryCake().makeStrawberryCake();
}
}
很显然,抽象工厂会增加系统的抽象性和理解难度。同时也规定了有可能被创建的产品的集合,导致产品中扩展新的产品困难,需要修改抽象接口。
在实际应用中,我们不能放强迫症,做那种纸上谈兵的事。需要根据实际业务情况,选择合适的设计模式。
网友评论