<HeadFirst设计模式>笔记——工厂模式

本文是《HeadFirst设计模式》笔记,主要探讨了工厂模式的三种形式:简单工厂、工厂方法和抽象工厂模式。通过文具店的例子,解释了如何使用这些模式降低耦合,依赖于抽象而非具体类,遵循“依赖倒置原则”。文章总结了各种工厂模式的特点,强调了它们在创建对象时的角色和价值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在客户端程序中过多的使用new去实例化就会造成耦合过强的问题。使用工厂模式可以有效地将这些实例化工作抽离到客户程序之外,使程序更多的依赖抽象类而不是具体的类,从而解耦。

简单工厂

简单工厂将同源类的实例化工作(new)归类一个独立的“工厂类”中执行,好让具体实例化的过程从客户代码中移除,起到解耦的作用。

书中以Pizza店为例,架构写的比较庞大,因为需要偷懒,这里以文具店卖笔为例。
Stationer为文具店实例,一共卖3种笔,Pen是所有笔的超类。客户需要获取其中一种笔时,只需向Stationer.getPen方法传入具体的type,即可获取到对应的Pen实例。
这里写图片描述

public class SimplePenFactory {

    public static Pen getPen(String type){
        if("art".equals(type)){
            return new ArtPen();
        }else if ("ink".equals(type)){
            return new InkPen();
        }else if("ballpoint".equals(type)){
            return new BallPointPen();
        }

        System.out.println("Invalid Type");
        return null;
    }
}

简单工厂是常见的一种用法,但书中认为“简单工厂”并不算真正的设计模式,而更像一种编程习惯。

工厂方法模式

“工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。”

通俗地来讲,就是将“工厂类”中创建对象的方法变成抽象的,并由继承它的子“工厂类”来实现,这样就可以由子类来具体决定实例化哪些类。

接着以文具店的例子来看,如果Pen的子类增多并有质量一般和质量较好的差别,商家增开到2家“文具店”并各自售卖不同质量的笔。使用工厂方法模式,这里要将“工厂类”分成2个(同超类),各自负责实例化不同质量的笔。

这里写图片描述

那么将原来的工厂类的接口getPen(String type)转成abstract,并创建2个子类GeneralStationer和DeluxeStationer,各自售卖一般和贵的文具笔,Pen的实例化工作也由这2个子类来实现(各自实现了getPen接口)。

public abstract class Stationer {

    public abstract Pen getPen(String type);
}

2个Stationer的子类,各自负责实例化不同质量的笔。尽管对客户来说,传入的type参数是一样的,但是实际上这2个“工厂”产生的实例并不同:

class GeneralStationer extends Stationer{

    @Override
    public Pen getPen(String type) {
        if("art".equals(type)){
            return new ArtPen();
        }else if ("ink".equals(type)){
            return new InkPen();
        }else if("ballpoint".equals(type)){
            return new BallPointPen();
        }
        System.out.println("Invalid Type");
        return null;
    }

}

class DeluxeStationer extends Stationer{

    @Override
    public Pen getPen(String type) {
        if("art".equals(type)){
            return new GoodArtPen();
        }else if ("ink".equals(type)){
            return new GoodInkPen();
        }else if("ballpoint".equals(type)){
            return new GoodBallPointPen();
        }
        System.out.println("Invalid Type");
        return null;
    }

}

工厂方法模式通过让工厂子类决定创建的具体对象时哪些,来达到将对象创建过程封装的目的。组成元素有:
1)创建者(工厂类)
2)产品类(单一产品类型,所有产品均继承自同一个父类)。

抽象工厂模式

“抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类”

抽象工厂与前面2种概念有点区别,抽象工厂模式目的是创建一组对象。
文具店当然不止有笔(Pen)卖,现在种类增加了橡皮擦(Eraser)和笔盒(PencilCase),而所有这些种类的文具都有好坏,有2个不同的文具工厂生产:
这里写图片描述

工厂方法模式只负责一种类型的创建,而抽象工厂模式可以创建一个产品的家族。事实上它们比较容易互相配合的,试想Pen类需要笔芯,笔头,笔壳组装而成,那么抽象工厂模式就可以为上游笔厂提供这些原料。

PS:例子中将Factory和各种文具设计成接口,是这本书推崇的原则——“少用继承多用组合”

“依赖倒置原则”

作者特意提到了这个原则:

“要依赖抽象,不要依赖具体类”

尽量依赖抽象,不要依赖具体类,便于得到更松耦合并有弹性的实现。

小结

  • 所有工厂都是用来封装对象创建的
  • 工厂方法使用继承,将创建对象的任务交给子类。
  • 抽象工厂使用对象组合,且创建对象的任务实现在接口中。
  • 工厂帮助我们针对抽象编程,不依赖具体类。所有工厂模式都通过减少程序和具体类之间的依赖促进松耦合。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值