第二章 设计模式--工厂模式 之工厂方法模式

工厂模式分为工厂方法模式和抽象工厂模式;

工厂模式是解决产品等级的问题;
抽象工厂是解决产品族的问题。
现在我们先来说一下工厂模式:

工厂方法模式:

定义:定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方法让类的实例化推迟到子类中进行。
适用场景:
1.创建对象需要大量重复的代码
2.客户端不依赖与产品类实例如何被创建、实现等细节
3.一个类通过其子类来指定创建哪个对象
利用面向对象的多态性和里氏替换原则,我们可以使用工厂模式。
**优点:**
1.客户端只需关心所需产品的工厂,无需关系实现细节。
2.加入新产品符合开闭原则,提高可扩展性。
** 缺点:  **
1.类的个数增多,增加复杂度
2.增加系统的抽象性和理解难度
下面我们来用coding来解释工厂方法的使用:

首先我们来创建各种电脑的父类:

/**
 * @program: adpn-pattern->Computer
 * @description: 电脑类
 * @author: Jstar
 * @create: 2019-11-17 11:18
 **/
public abstract class Computer {
    public abstract void process();
}

接下来我们来创建3个电脑父类的实现:

public class ThinkpadComputer extends Computer {
    @Override
    public void process() {
        System.out.println("这里可写业务代码,但我们模拟--生产联想电脑");
    }
}
public class MacbookComputer extends Computer {
    @Override
    public void process() {
        System.out.println("这里可写业务代码,但我们模拟--生产苹果电脑");
    }
}
public class HpComputer extends Computer {
    @Override
    public void process() {
        System.out.println("这里可写业务代码,但我们模拟--生产惠普电脑");
    }
}

创建电脑工厂的父类:

/**
 * @program: adpn-pattern->ComputerFactory
        * @description: 生产电脑工厂类
        * @author: Jstar
        * @create: 2019-11-17 11:34
        **/
public abstract  class ComputerFactory {
    public abstract Computer getComputer();
}

创建 3个 电脑工厂子类的实现:

public class ThinkpadComputerFactory extends ComputerFactory {
    @Override
    public Computer getComputer() {
        return new ThinkpadComputer ();
    }
}
public class MacbookComputerFactory extends ComputerFactory {
    @Override
    public Computer getComputer() {
        return new MacbookComputer();
    }
}
public class HpComputerFactory extends ComputerFactory {
    @Override
    public Computer getComputer() {
        return new HpComputer();
    }
}

我们使用客户端来调用上面的工厂方法:

/**
 * @program: adpn-pattern->Test
 * @description: 测试类
 * @author: Jstar
 * @create: 2019-11-17 11:42
 **/
public class Test {
    public static void main(String[] args) {
        ComputerFactory macbookComputerFactory = new MacbookComputerFactory();
        ComputerFactory thinkpadComputerFactory = new ThinkpadComputerFactory();
        ComputerFactory hpComputerFactory = new HpComputerFactory();

        Computer macbookComputer = macbookComputerFactory.getComputer();
        Computer thinkpadComputer = thinkpadComputerFactory.getComputer();
        Computer hpComputer = hpComputerFactory.getComputer();
        macbookComputer.process();
        thinkpadComputer.process();
        hpComputer.process();
    }
}

看一下执行结果

这里可写业务代码,但我们模拟--生产苹果电脑
这里可写业务代码,但我们模拟--生产联想电脑
这里可写业务代码,但我们模拟--生产惠普电脑

至此,工厂方法模式演示完了,下面我们来看一下UML图:

在这里插入图片描述
再来查看一下调用链:
在这里插入图片描述
我们再来看一下工厂方法的定义:

	定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方法让类的实例化推迟到子类中进行。

在此例中 ComputerFactory 就是一个工厂抽象类,具体的实现和实例化创建哪种类型都在 子类的 ThinkpadComputerFactory、MacbookComputerFactory、HpComputerFactory 中定义了。

下面我们来看一下,jdk中使用工厂方法的地方:
1.看一下 集合 Collection 中的 iterator() 这个方法:

我们发现有很多类重写这个方法:
在这里插入图片描述
那我们来看看熟悉的 ArrayList 是怎么重写的。

在这里插入图片描述
从图上我们可以看到,Collection 就是 抽象的工厂接口,具体的实现 是由像 ArrayList 这样的工厂实现类来实现的。
在这里插入图片描述
Collection 就像上面讲的ComputerFactory, ArrayList 就像 MacbookComputerFactory,
ArrayList 中 iterator() 方法返回的 Itr 类就是 就像具体生产出来的 MacbookComputer , 而 Itr 实现的 Iterator ,就像是 Computer 。
所以,Collection 集合中 iterator() 方法也有使用 工厂方法,具体的实现由ArrayList 这样的子类完成。

2.我们再来看一个例子:
LoggerFactory 的 getLogger() 方法:
public static Logger getLogger(String name) {
        ILoggerFactory iLoggerFactory = getILoggerFactory();
        return iLoggerFactory.getLogger(name);
    }

其中的 ILoggerFactory 是一个接口,定义了 getLogger(String var1) 方法,具体的 getLogger(String var1) 方法由子类实现。

public interface ILoggerFactory {
    Logger getLogger(String var1);
}

子类 NOPLoggerFactory 实现了ILoggerFactory ,重写了 getLogger(String name) 方法,返回的 Logger 对象。

public class NOPLoggerFactory implements ILoggerFactory {
    public NOPLoggerFactory() {
    }

    public Logger getLogger(String name) {
        return NOPLogger.NOP_LOGGER;
    }
}

最终我们看到 返回的 NOPLogger 也是继承 Logger。
至此,这也是一例 工厂方法模式。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值