高级软件设计简答题汇总

设计模式和类库有什么不同

  • 定义与目的

    解决问题,重复使用的框架,经过验证的最佳实践,解决设计问题

    封装特定功能的类和接口的集合,提供具体实现

  • 抽象级别

    更高级别抽象,方法论,组织代码和模块

    具体实现,提供可直接使用的代码

  • 通用性和使用范围

    通用性更高,适合多种语言和项目,举例

    类库与特定编程语言绑定,Java Spring框架

  • 重用程度

    重用思想和方法,而非代码

    重用代码

工厂设计模式的三个OO原则

  • 单一职责原则

    一个类应当只有一个引起变化的原因。创建对象的职责被分配给专门的工厂,可以将创建与使用分离。

    工厂只关心对象的创建,而不关心对象的具体使用。

  • 依赖倒置原则

    高层模块不应当依赖于底层模块,都应该依赖于抽象。

    抽象不应该依赖于细节,细节应该依赖于抽象。

    客户端代码依赖于抽象的工厂,而不依赖于具体的工厂实现类。

  • 开闭原则

    软件实体应当对扩展开放,对修改封闭。工厂方法模式允许系统不修改代码,引入新类型的对象,可以添加新的工厂扩展系统。

什么是设计模式,什么是design pattern catalog?

  • 在软件工程中,针对特定问题的典型解决方案的一种标准化描述。最佳实践,解决问题,不是代码,而是指导方案

    包含模式名称、问题、解决方案、效果

    分三大类:创建型、结构型、行为型

  • Design pattern catalog 是指收集多种设计模式的目录。包含详细描述、示例、优缺点。

为什么“依赖倒置原则”被认为是大多数设计模式的核心?

  • 先介绍依赖倒置原则,高层不应依赖低层,应该依赖于抽象。抽象不应该依赖于细节,细节应该依赖于抽象。
  • 降低模块之间的耦合。

比较策略模式和状态模式

  • 都是行为型设计模式,然后从目的、应用场景、实现、优缺点来讲

    目的:策略模式允许运行时选择算法或行为,状态模式允许对象改变内部状态来改变行为

    应用场景

    策略模式

    • 用于多种类似算法或行为的互换使用(不同排序算法),运行时可切换
    • 避免条件语句,去除条件语句决定执行哪个算法
    • 封装算法的变化

    状态模式

    • 对象行为依赖于其状态,行为随着状态改变而改变
    • 对象有复杂的状态逻辑,状态转换明确
    • 避免对象行为的膨胀

    实现

    • 策略模式定义策略接口,创建具体策略类,上下文使用策略接口作为字段,调用具体策略实现
    • 状态模式将每种状态封装成独立的类,将状态转换的逻辑放在状态类内部实现

    优缺点

    • 策略模式提高复用性,独立于客户端变化,但需了解策略之间差异,增加了复杂性
    • 状态模式将逻辑分散到状态类中,易于扩展状态,但引入很多状态类,增加系统复杂性

比较适配器、外观和装饰器设计模式的意图和模式

  • 适配器模式将一个类的接口转换成期望的另一个类的接口,让不兼容的类一起工作(整合第三方库)
  • 外观模式提供统一的接口,访问子系统的一群接口,使子系统更易使用(简化客户端与复杂系统的交互)
  • 装饰器模式动态地给对象添加额外的职责而不改变对象接口,比生成子类灵活(动态添加功能)

比较适配器模式、装饰器模式和代理模式的目的与结构差异。

  • 都是结构型设计模式,然后写目的和结构

    适配器模式的目的是解决接口不兼容问题,通过包装已有对象将其接口转换为客户端期望的接口

    装饰器模式的目的是在不修改原对象的情况下动态地为对象增加功能,其结构呈现链式包装

    代理模式的目的是控制对对象的访问,在客户端与真实对象之间提供一个代理层。

    三者在结构上都通过组合方式包装对象,

比较透明组合和安全组合。

  • 讲定义和优缺点

    定义:透明组合的Component中包含管理子部件的操作,对于Leaf节点和Composite节点都可见。而安全组合管理子部件的操作不再Component接口中定义,而是只在Composite节点类中实现。

    优缺点

    透明组合客户端通义对待叶节点和容器节点,不必关心操作的是哪个。但牺牲了单一职责原则,叶节点包含多余的操作可能引起运行时错误。

    安全组合叶节点不提供无关的操作,遵循单一职责原则,更加安全。但牺牲了透明性,处理节点要进行类型判断,增加了代码的复杂性。

比较工厂方法模式与抽象工厂模式的适用场景。

  • 工厂方法模式适用于系统只涉及一种产品类型,子类决定创建哪种产品,产品之间没有强关联(不同类型的解析器)
  • 抽象工厂模式适用于创建一组相关或相互依赖产品族的产品族的场景,强调产品一致性(不同风格的UI组件)

比较组合模式与装饰模式在结构上的异同。

  • 相同点:都使用抽象组件(Component),都通过递归方式组合对象,而不是继承。
  • 不同点:Composite中包含多个Component,而Decorator中只包装一个Component。组合模式关注层次结构,形成树结构,而装饰模式关注功能扩展,形成链式结构。

说明装饰者模式如何体现开闭原则和合成复用原则。

  • 先扯两个概念。
  • 开闭原则:装饰者模式通过引入装饰类在不修改原有类的情况下动态扩展对象功能,完美体现了开闭原则。
  • 合成复用原则:通过对象组合实现功能扩展,避免了继承带来的类爆炸问题,符合合成复用原则。

说明观察者模式如何体现依赖倒置原则与迪米特法则。

  • 先扯概念
  • 主题和观察者通过抽象接口解耦,高层模块 Subject 不再依赖具体实现,体现依赖倒置原则。
  • 主题对象只与观察者接口通信,不与观察者的具体实现发生依赖,符合迪米特法则。

说明模板方法模式如何体现开闭原则。

  • 开闭原则定义
  • 模板方法模式通过固定算法骨架、延迟步骤实现,使系统在不修改算法结构的前提下即可扩展新行为,从而体现了开闭原则。

说明组合模式如何体现里氏替换原则。

  • 组合模式通过为叶子对象和组合对象定义统一的抽象组件接口,使客户端对单个对象和组合对象的使用具有一致性,从而保证了任何组件子类对象都可以替换抽象组件出现的位置而不影响程序行为,体现了里氏替换原则。

观察者模式中的update方法是否必须?请说明理由。

  • 观察者模式中的update方法通常是必须的
  • 先讲角色:观察者(Observer)和被观察者(Subject)。被观察者维护一个观察者列表,并在状态变化时通知它们。观察者需要有一个方法来接收并响应这些通知,这就是 update 方法的作用。通过 update 方法,观察者可以得知被观察者的状态变化并作出相应的反应。
  • 再讲通知方式:当被观察者的状态改变时,它会调用每个注册观察者的 update 方法,以此来通知观察者其状态已改变。
  • 灵活性与一致性:在某些实现中,update 方法可以接收参数以提供关于状态变化的更多信息。
  • update概念上必需,但具体形式并非固定,可以通过回调、事件机制等方式实现通知。

在什么情况下应当使用策略模式?举例说明。

  • 用于多种类似算法或行为的互换使用(不同排序算法),运行时可切换
  • 避免条件语句,去除条件语句决定执行哪个算法
  • 封装算法的变化