整理好了!2024年最常见 20 道设计模式面试题(二)

上一篇地址:整理好了!2024年最常见 20 道设计模式面试题(一)-CSDN博客

三、解释工厂方法模式和抽象工厂模式的区别。

工厂方法模式和抽象工厂模式都是创建型设计模式,它们用于创建对象,但它们在应用场景和实现方式上存在一些关键的区别。

工厂方法模式(Factory Method Pattern)

工厂方法模式定义了一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法让类的实例化推迟到子类中进行。

特点:

  • 定义了一个创建对象的接口。
  • 让子类决定实例化哪一个类。
  • 封装了对象的创建过程。

适用场景:

  • 当需要创建的对象类型较多,且这些对象具有共同的接口或抽象类时。
  • 当需要将对象的创建和使用分离,以提高灵活性和可扩展性。

实现方式: 工厂方法模式通常包含以下几个角色:

  • 产品(Product):定义了产品的接口。
  • 具体产品(Concrete Product):实现产品接口的具体类。
  • 工厂(Creator):定义了创建产品的接口。
  • 具体工厂(Concrete Creator):实现工厂接口,具体实例化某个产品。

抽象工厂模式(Abstract Factory Pattern)

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

特点:

  • 创建一系列相关或依赖的产品对象。
  • 封装了产品系列的创建过程。
  • 允许系统独立于产品的实现。

适用场景:

  • 当需要创建的产品族具有多个等级结构时。
  • 当系统需要提供相同类型的产品族,但具体类型在运行时才确定时。

实现方式: 抽象工厂模式通常包含以下几个角色:

  • 抽象产品(Abstract Product):定义了产品的接口。
  • 具体产品(Concrete Product):实现抽象产品的接口。
  • 抽象工厂(Abstract Factory):提供了创建抽象产品的接口。
  • 具体工厂(Concrete Factory):实现抽象工厂的接口,具体实例化某个产品族。

区别:

  1. 产品结构:工厂方法模式创建单一产品,而抽象工厂模式创建产品族。
  2. 工厂结构:工厂方法模式只有一个工厂类,而抽象工厂模式有多个工厂类,每个工厂类负责创建一个产品族。
  3. 扩展性:工厂方法模式易于添加新的产品,但增加新的产品等级结构需要修改工厂类;抽象工厂模式易于添加新的产品等级结构,但增加新的产品需要修改所有的工厂类。
  4. 复杂性:工厂方法模式相对简单,适用于产品结构单一的情况;抽象工厂模式适用于产品结构复杂,需要创建多个相关产品的情况。

示例:

假设我们有一个软件系统,需要创建不同类型的图形对象,如圆形和矩形。

  • 工厂方法模式:我们可以有一个Shape接口和两个具体类CircleRectangle。然后,我们有一个ShapeFactory接口和两个具体工厂类CircleFactoryRectangleFactory,每个工厂类分别创建一个形状。

  • 抽象工厂模式:如果我们的系统需要同时创建颜色和形状,我们可以定义一个Color接口和Shape接口,以及它们的具体实现。然后,我们有一个AbstractFactory接口,它包含创建颜色和形状的方法。具体工厂类如RedCircleFactoryBlueRectangleFactory实现这个接口,分别创建红色圆形和蓝色矩形。

通过这种方式,工厂方法模式和抽象工厂模式提供了灵活和可扩展的方式来创建对象,适应不同的设计需求。

四、描述建造者模式,并给出一个使用场景。

建造者模式(Builder Pattern)是一种对象创建的设计模式,用于构建一个复杂对象。它将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建出不同表示的对象。

建造者模式的关键特点:

  1. 复杂对象的构建:用于创建具有多个属性和配置的复杂对象。
  2. 分步骤构建:对象的构建过程被分解成多个步骤,逐步构建。
  3. 灵活性:允许在构建过程中修改构建步骤,以创建不同的对象表示。
  4. 封装性:隐藏了对象构建的细节,只暴露构建完成的对象。

建造者模式的角色:

  1. 产品(Product):最终创建的对象。
  2. 建造者(Builder):创建产品对象的接口,定义创建产品的方法。
  3. 具体建造者(Concrete Builder):实现建造者接口,具体构建产品的方法。
  4. 指挥者(Director):管理建造过程,调用建造者的方法来创建产品。

使用场景:

建造者模式适用于以下场景:

  • 对象的构建过程复杂,涉及多个步骤。
  • 对象的构建过程可能会变化,需要灵活性。
  • 需要创建具有不同属性或配置的多种复杂对象。

示例使用场景:汽车制造

假设我们正在设计一个汽车制造系统,汽车由多个部件组成,如发动机、轮胎、车身等。使用建造者模式,我们可以定义一个Car类作为产品,一个CarBuilder接口作为建造者,以及具体的建造者实现,如EconomyCarBuilderLuxuryCarBuilder

示例代码(Java):

// 产品角色:汽车
interface Car {
    void setEngine(String engine);
    void setWheels(String wheels);
    void setBody(String body);
    // 省略其他部件设置方法
}

// 具体产品:经济型汽车
class EconomyCar implements Car {
    private String engine;
    private String wheels;
    private String body;
    // 实现方法
}

// 具体产品:豪华型汽车
class LuxuryCar implements Car {
    private String engine;
    private String wheels;
    private String body;
    // 实现方法
}

// 建造者角色:汽车建造者接口
interface CarBuilder {
    void setEngine();
    void setWheels();
    void setBody();
    // 省略其他部件设置方法
    Car getCar();
}

// 具体建造者:经济型汽车建造者
class EconomyCarBuilder implements CarBuilder {
    private Car car;

    public EconomyCarBuilder() {
        this.car = new EconomyCar();
    }

    public void setEngine() {
        // 设置经济型发动机
    }

    public void setWheels() {
        // 设置经济型轮胎
    }

    public void setBody() {
        // 设置经济型车身
    }

    public Car getCar() {
        return car;
    }
}

// 指挥者角色:汽车制造指挥者
class CarDirector {
    public Car constructCar(CarBuilder builder) {
        builder.setEngine();
        builder.setWheels();
        builder.setBody();
        // 调用其他设置方法
        return builder.getCar();
    }
}

// 使用建造者模式创建汽车
public class BuilderPatternDemo {
    public static void main(String[] args) {
        CarBuilder builder = new EconomyCarBuilder();
        CarDirector director = new CarDirector();
        Car car = director.constructCar(builder);
        // 使用car
    }
}

在这个示例中,CarDirector类作为指挥者,通过调用CarBuilder接口定义的方法来构建汽车。EconomyCarBuilderLuxuryCarBuilder作为具体建造者,实现了不同的汽车构建逻辑。这样,我们可以灵活地创建不同类型的汽车,而不需要修改构建逻辑。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值