• 赶紧收藏!2024 年最常见 20道设计模式面试题(二)


    上一篇地址:赶紧收藏!2024 年最常见 20道设计模式面试题(一)-CSDN博客

    三、解释抽象工厂模式,并给出一个实际应用的例子。

    抽象工厂模式是一种创建型设计模式,用于创建一系列相关或依赖对象的接口,而无需指定它们具体的类。这种模式通常用于当需要生成一组对象时,这些对象具有共同的抽象特性,但是具体实现可能因情况而异。

    抽象工厂模式的特点:

    1. 抽象化:定义了一个创建对象的接口,允许通过子类来生成具体对象。
    2. 封装性:客户端不需要知道具体的类是如何实现的,只需要知道它们遵循相同的接口。
    3. 灵活性:可以独立于具体类的变化而变化,易于扩展新的产品族。
    4. 解耦:将类的实例化延迟到子类中进行。

    抽象工厂模式的结构:

    1. 抽象工厂(Abstract Factory):声明了一组创建对象的方法,每个方法对应一种产品。
    2. 具体工厂(Concrete Factory):实现抽象工厂的接口,生成一组具体产品。
    3. 抽象产品(Abstract Product):定义了产品的接口。
    4. 具体产品(Concrete Product):实现了抽象产品的接口,由具体工厂创建。

    抽象工厂模式的实现步骤:

    1. 定义抽象产品类和接口。
    2. 定义具体产品类,实现抽象产品接口。
    3. 定义抽象工厂类,提供创建抽象产品的接口。
    4. 定义具体工厂类,实现抽象工厂的接口,生成具体产品。

    抽象工厂模式的示例(Java语言):

    1. // 抽象产品A
    2. interface ProductA {
    3. void doSomething();
    4. }
    5. // 具体产品A1
    6. class ConcreteProductA1 implements ProductA {
    7. public void doSomething() {
    8. System.out.println("具体产品A1的doSomething方法");
    9. }
    10. }
    11. // 抽象产品B
    12. interface ProductB {
    13. void doSomething();
    14. }
    15. // 具体产品B1
    16. class ConcreteProductB1 implements ProductB {
    17. public void doSomething() {
    18. System.out.println("具体产品B1的doSomething方法");
    19. }
    20. }
    21. // 抽象工厂
    22. interface Factory {
    23. ProductA createProductA();
    24. ProductB createProductB();
    25. }
    26. // 具体工厂1
    27. class ConcreteFactory1 implements Factory {
    28. public ProductA createProductA() {
    29. return new ConcreteProductA1();
    30. }
    31. public ProductB createProductB() {
    32. return new ConcreteProductB1();
    33. }
    34. }

    使用场景:

    抽象工厂模式的一个实际应用例子是GUI工具包。假设你正在开发一个应用程序,需要支持多种不同的GUI工具包,例如Windows风格和Mac风格。每种风格都有自己的按钮、文本框等控件。

    1. // GUI组件的抽象产品
    2. interface Button {
    3. void paint();
    4. }
    5. interface TextBox {
    6. void paint();
    7. }
    8. // Windows风格的具体产品
    9. class WindowsButton implements Button {
    10. public void paint() {
    11. System.out.println("绘制Windows风格的按钮");
    12. }
    13. }
    14. class WindowsTextBox implements TextBox {
    15. public void paint() {
    16. System.out.println("绘制Windows风格的文本框");
    17. }
    18. }
    19. // Mac风格的具体产品
    20. class MacButton implements Button {
    21. public void paint() {
    22. System.out.println("绘制Mac风格的按钮");
    23. }
    24. }
    25. class MacTextBox implements TextBox {
    26. public void paint() {
    27. System.out.println("绘制Mac风格的文本框");
    28. }
    29. }
    30. // 抽象工厂
    31. interface GUIFactory {
    32. Button createButton();
    33. TextBox createTextBox();
    34. }
    35. // Windows风格的具体工厂
    36. class WindowsFactory implements GUIFactory {
    37. public Button createButton() {
    38. return new WindowsButton();
    39. }
    40. public TextBox createTextBox() {
    41. return new WindowsTextBox();
    42. }
    43. }
    44. // Mac风格的具体工厂
    45. class MacFactory implements GUIFactory {
    46. public Button createButton() {
    47. return new MacButton();
    48. }
    49. public TextBox createTextBox() {
    50. return new MacTextBox();
    51. }
    52. }

    在这个例子中,GUIFactory是一个抽象工厂,用于创建GUI组件。WindowsFactoryMacFactory是具体工厂,分别生成Windows和Mac风格的GUI组件。应用程序可以根据用户的选择或系统环境来使用不同的工厂,从而生成相应风格的GUI组件。这样,应用程序的GUI就可以很容易地适应不同的操作系统风格,而不需要修改大量的代码。

    四、建造者模式是如何解决复杂对象构建问题的?

    建造者模式(Builder Pattern)是一种创建型设计模式,用于解决复杂对象的构建问题。它允许通过逐步构建一个复杂对象来分离对象的构建过程和表示,使得同一个构建过程可以创建不同的表示。

    建造者模式的特点:

    1. 分离构建与表示:将对象的构建过程从其表示中分离出来,使得相同的构建过程可以创建不同的表示。
    2. 灵活性:可以控制复杂对象的构建过程,允许逐步构建对象,并且可以在构建过程中修改构建步骤。
    3. 可扩展性:当需要添加新的产品属性或构造方法时,不需要修改现有的构建类,只需要添加新的建造者类即可。
    4. 减少复杂性:避免了使用大量的可选参数,这些参数可能会使构造函数变得复杂且难以管理。

    建造者模式的结构:

    1. 产品(Product):需要构建的复杂对象。
    2. 建造者(Builder):创建产品的接口,定义了一系列的设置方法,用于设置产品的不同部分。
    3. 具体建造者(Concrete Builder):实现建造者接口,具体实现构建产品的方法。
    4. 指挥者(Director):负责使用建造者来构建产品的过程,它不依赖于具体建造者的具体实现。

    建造者模式的实现步骤:

    1. 定义产品类,包含多个属性和构造这些属性的方法。
    2. 定义建造者接口,包含设置产品属性的方法和一个返回产品实例的方法。
    3. 实现具体建造者类,实现建造者接口,并构建最终的产品实例。
    4. 定义指挥者类,包含一个方法,接受一个建造者对象,并使用它来构建产品。

    建造者模式的示例(Java语言):

    1. // 产品类
    2. class Product {
    3. private String part1;
    4. private String part2;
    5. public void setPart1(String part1) {
    6. this.part1 = part1;
    7. }
    8. public void setPart2(String part2) {
    9. this.part2 = part2;
    10. }
    11. @Override
    12. public String toString() {
    13. return "Product{" +
    14. "part1='" + part1 + '\'' +
    15. ", part2='" + part2 + '\'' +
    16. '}';
    17. }
    18. }
    19. // 建造者接口
    20. interface Builder {
    21. void setPart1(String part1);
    22. void setPart2(String part2);
    23. Product build();
    24. }
    25. // 具体建造者
    26. class ConcreteBuilder implements Builder {
    27. private Product product = new Product();
    28. public void setPart1(String part1) {
    29. product.setPart1(part1);
    30. }
    31. public void setPart2(String part2) {
    32. product.setPart2(part2);
    33. }
    34. public Product build() {
    35. return product;
    36. }
    37. }
    38. // 指挥者
    39. class Director {
    40. public Product construct(Builder builder) {
    41. builder.setPart1("Part1");
    42. builder.setPart2("Part2");
    43. return builder.build();
    44. }
    45. }

    使用场景:

    建造者模式非常适合于以下场景:

    • 当创建复杂对象的算法应该独立于对象本身的表示时。
    • 当需要创建一个复杂对象的不同变体时。
    • 当希望对象的创建过程与使用过程分离时。

    例如,假设你正在构建一个汽车配置系统,汽车可能有不同的引擎、轮胎、颜色等配置选项。使用建造者模式,你可以定义一个汽车建造者接口,然后为每种配置实现一个具体的建造者类。指挥者类可以根据不同的需求调用不同的建造者来构建具有特定配置的汽车实例。

    通过这种方式,建造者模式提供了一种灵活且可扩展的方式来构建复杂的对象,同时保持了代码的清晰和易于管理。

  • 相关阅读:
    Perl基础入门指南:从零开始掌握Perl编程
    Day45-9大内置对象、JSP标签、JSTL标签、EL表达式、JavaBean
    jQuery 语法
    PT:dmsa如何设置don‘t use
    【Java开发】 Spring 04:云服务器 Docker 环境下安装 Redis 并连接 Spring 项目实现简单 CRUD
    企业补丁管理-windows/Mac/Linux打补丁
    单片机论文参考:4、基于单片机的智能避障小车
    聚观早报 | 长二丁成功发射北京三号B星;​字节推出“悟空搜索”
    pc端使用微信扫码登录(思路篇)
    [算法]滑动窗口
  • 原文地址:https://blog.csdn.net/weixin_42922481/article/details/139754491