自学内容网 自学内容网

java中23种设计模式的优缺点

文兴一言

设计模式分为创建型模式、结构型模式和行为型模式。以下是每种设计模式及其优缺点的详细介绍:

一、创建型模式

  1. 简单工厂模式

    • 优点:通过一个共同的工厂类来创建对象,将对象的创建逻辑封装在一个地方,客户端只需要与工厂进行交互,而不需要关心具体的创建过程。
    • 缺点:当产品类型较多时,工厂类可能会变得庞大而复杂;添加新的产品时需要修改工厂类的代码,违反了开闭原则。
  2. 工厂方法模式

    • 优点:将对象的创建延迟到子类中实现,每个具体子类都可以创建自己特定类型的对象,符合开闭原则;提供了良好的封装性,代码结构清晰;扩展性好,在增加产品类的情况下,只需要适当修改具体的工厂类或扩展一个工厂类。
    • 缺点:需要Creator和相应的子类作为工厂方法的载体,如果应用模型不需要creator和子类存在,则需要增加一个类层次。
  3. 抽象工厂模式

    • 优点:提供一个接口用于创建一系列相关或相互依赖的对象,客户端通过接口使用这些对象,能够在不指定具体实现类的情况下创建一系列产品;易于交换产品系列;使具体的创建实例过程与客户端分离。
    • 缺点:新增加一种产品族时,需要修改抽象工厂的接口及所有的具体工厂类,违反了开闭原则;实现增加功能时,需改动的地方比较多。
  4. 建造者模式

    • 优点:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示;建造模式的使用使得产品的内部表象可以独立地变化;使用建造模式可以使客户端不必知道产品内部组成的细节。
    • 缺点:如果产品内部变化复杂,会增加系统的难度和运行成本;建造者模式的“加工工艺”是暴露的,这样使得建造者模式更加灵活,也使得工艺变得对客户不透明。
  5. 原型模式

    • 优点:通过复制现有对象来创建新对象,提高了创建对象的效率;允许动态地增加或减少产品类。
    • 缺点:每个类都需要实现克隆方法,包括引用类型的属性也需要实现深拷贝,否则克隆对象的修改会影响到原始对象;克隆位于类内部,不易于修改源代码。
  6. 单例模式

    • 优点:确保一个类只有一个实例,并提供全局访问点;节约系统资源,提高系统性能。
    • 缺点:不易扩展;摧毁方法未定义,没有好的方法去摧毁一个单例,或者解除其责任;不能继承,从单例派生的类并不是单例;效率问题,每次调用instance方法都会执行if语句,可能造成多余的计算;不透明性,单例的使用者知道它们正在使用一个单例,因为它们必须要调用instance方法。

二、结构型模式

  1. 适配器模式

    • 优点:将一个类的接口转换成客户端所期望的接口,使得原本不兼容的类可以协同工作;增加类的复用性;灵活性和扩展性较好。
    • 缺点:不能适配多个适配者;目标抽象类只能为接口,不能为类。
  2. 桥接模式

    • 优点:将抽象部分与它的实现部分分离,使它们都可以独立地变化;提高了系统的可扩展性。
    • 缺点:增加了系统的理解与设计难度。
  3. 装饰模式

    • 优点:动态地给一个对象增加一些额外的职责,就增加对象功能来说,装饰模式比生成子类实现更为灵活;不会导致类的个数急剧增加;可以通过一种动态的方式来扩展一个对象的功能,从而实现不同的行为;可以对一个对象进行多次装饰,通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合,得到功能更为强大的对象;具体构件类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构件类和具体装饰类,原有类库代码无须改变,符合“开闭原则”。
    • 缺点:使用装饰模式进行系统设计时将产生很多小对象,在一定程度上影响程序的性能;装饰模式提供了一种比继承更加灵活机动的解决方案,但同时也意味着比继承更加易于出错,排错也很困难,较为繁琐。
  4. 组合模式

    • 优点:组合模式可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,它让客户端忽略了层次的差异,方便对整个层次结构进行控制;客户端可以一致地使用一个组合结构或其中单个对象,不必关心处理的是单个对象还是整个组合结构,简化了客户端代码;在组合模式中增加新的容器构件和叶子构件都很方便,无须对现有类库进行任何修改,符合“开闭原则”。
    • 缺点:建含有特定对象的类难以实现;组合模式可能会导致设计中的一些对象变得过于一般化,使得系统变得复杂。
  5. 外观模式

    • 优点:对客户端屏蔽了子系统组件,使得客户端代码变得很简单;子系统发生变化时,不会影响到调用它的客户端,只需调整外观类即可;一个子系统的修改,对其他子系统没有任何影响,而且子系统内部变化也不会产生影响。
    • 缺点:不能很好地限制客户端直接使用子系统类;如果设计不当,增加新的子系统可能需要修改外观类的源代码,违背了“开放-封闭”原则。
  6. 享元模式

    • 优点:可以减少内存中对象的数量,从而节约系统资源,提高系统性能;享元模式的外部状态相对独立,而且不会影响内部状态,从而使得享元对象可以在不同环境中被共享。
    • 缺点:使得系统变得复杂,因为需要分离出内部状态和外部状态;享元模式需要维护一个记录了系统已有的所有享元的列表,这本身需要耗费资源。

三、行为型模式

  1. 代理模式

    • 优点:给某一个对象提供一个代理或占位符,并由代理对象来控制对原对象的访问;协调调用者和被调用者,在一定程度上降低系统的耦合度;可以针对抽象主题角色进行编程,增加和更换代理类的时候不需要修改源代码;投资小,只需购买公司一定数量的产品或者缴纳一定代理费用即可成为代理,自主进行销售经营等活动。
    • 缺点:在客户端和对象之间增加了代理,所以可能会造成请求的处理速度变慢;实现代理模式需要额外的工作;由于信息不对称,代理在合作期内可能遇到需要垫付在途资金的情况,这些资金的风险就需要代理商自己承担了。
  2. 访问者模式

    • 优点:将数据结构与数据操作分离;增加新的操作很容易,即增加新的访问者。
    • 缺点:具体元素对访问者公布细节,违反了迪米特原则;具体元素变更比较困难;违反了依赖倒置原则,依赖了具体类,没有依赖抽象。
  3. 状态模式

    • 优点:将不同的状态隔离,把各种状态的转换逻辑分布到State的子类中,减少相互依赖;增加新的状态非常简单。
    • 缺点:状态多的业务场景导致类的数目增加,系统变复杂。

请注意,每种设计模式都有其特定的适用场景和优缺点,选择适当的设计模式取决于具体的需求和设计目标,以及对系统的灵活性、可维护性和可扩展性的要求。

通义灵码

创建型模式

  1. 单例模式 (Singleton Pattern)

    • 优点
      • 确保一个类只有一个实例,节省系统资源。
      • 提供全局访问点,方便使用。
    • 缺点
      • 违反单一职责原则,承担了过多的职责。
      • 单例模式通常不是线程安全的,需要额外处理。
      • 滥用单例会导致程序结构混乱,难以理解和维护。
  2. 工厂方法模式 (Factory Method Pattern)

    • 优点
      • 封装对象的创建过程,提高代码的灵活性和可扩展性。
      • 解耦客户端和具体产品类,客户端不需要知道产品的具体类。
    • 缺点
      • 增加了系统的复杂性,引入了更多的类。
      • 如果产品类层次结构复杂,工厂类也会变得复杂。
  3. 抽象工厂模式 (Abstract Factory Pattern)

    • 优点
      • 提供了一种创建一系列相关或依赖对象的接口,而无需指定它们具体的类。
      • 容易交换产品系列,只需改变具体工厂即可。
    • 缺点
      • 系统中类的数量增加,增加了系统的复杂性。
      • 抽象工厂模式对产品的扩展支持不好,增加新产品需要修改工厂接口。
  4. 建造者模式 (Builder Pattern)

    • 优点
      • 将复杂的构建过程分解成多个步骤,提高代码的可读性和可维护性。
      • 可以创建不同类型的对象,而不需要改变构建过程。
    • 缺点
      • 代码量增加,引入了更多的类。
      • 如果产品对象比较简单,使用建造者模式可能会显得过于复杂。
  5. 原型模式 (Prototype Pattern)

    • 优点
      • 通过复制现有对象来创建新对象,减少了创建对象的时间和资源消耗。
      • 简化对象的创建过程,客户端不需要知道对象的具体类。
    • 缺点
      • 需要实现克隆方法,增加了类的复杂性。
      • 如果对象的属性很多,深克隆和浅克隆的选择会增加复杂性。

结构型模式

  1. 适配器模式 (Adapter Pattern)

    • 优点
      • 提高类的复用性,可以将已有的类复用而不必修改源代码。
      • 增加了类的透明性和灵活性。
    • 缺点
      • 过多的适配器会使系统更加复杂。
      • 类适配器模式会增加类的数量,对象适配器模式会增加对象的数量。
  2. 桥接模式 (Bridge Pattern)

    • 优点
      • 将抽象部分与实现部分分离,提高了系统的可扩展性。
      • 客户端可以独立于实现部分进行操作。
    • 缺点
      • 引入了更多的抽象类和接口,增加了系统的复杂性。
      • 实现部分的修改会影响客户端代码。
  3. 组合模式 (Composite Pattern)

    • 优点
      • 客户端可以一致地对待单个对象和组合对象。
      • 简化了客户端代码,提高了代码的可读性和可维护性。
    • 缺点
      • 设计较为复杂,增加了类的数量。
      • 如果层次结构过深,会增加系统的复杂性。
  4. 装饰器模式 (Decorator Pattern)

    • 优点
      • 动态地给对象添加新的功能,灵活且透明。
      • 符合开闭原则,扩展功能时不需要修改原有代码。
    • 缺点
      • 装饰器的使用会增加对象的数量,可能导致性能下降。
      • 多层装饰器的使用会使代码难以理解和维护。
  5. 外观模式 (Facade Pattern)

    • 优点
      • 为子系统提供了一个简化的接口,降低了子系统的复杂性。
      • 提高了子系统的独立性和可维护性。
    • 缺点
      • 不符合开闭原则,新增功能时需要修改外观类。
      • 过度使用外观模式可能会导致系统结构模糊。
  6. 享元模式 (Flyweight Pattern)

    • 优点
      • 通过共享资源来减少内存使用,提高性能。
      • 适用于需要大量相似对象的场景。
    • 缺点
      • 增加了系统的复杂性,引入了更多的类和方法。
      • 对象的外部状态管理可能会增加代码的复杂性。
  7. 代理模式 (Proxy Pattern)

    • 优点
      • 可以控制对真实对象的访问,提供额外的功能(如延迟初始化、权限控制)。
      • 提高了系统的灵活性和安全性。
    • 缺点
      • 代理类的引入会增加系统的复杂性。
      • 如果代理类和真实类的方法较多,代码量会显著增加。

行为型模式

  1. 责任链模式 (Chain of Responsibility Pattern)

    • 优点
      • 解耦请求的发送者和接收者,提高了系统的灵活性。
      • 客户端可以动态地指定请求的处理者。
    • 缺点
      • 请求可能不会被处理,需要谨慎设计。
      • 过多的责任链节点会增加系统的复杂性。
  2. 命令模式 (Command Pattern)

    • 优点
      • 将请求封装成对象,可以方便地实现请求的排队、记录日志等功能。
      • 符合开闭原则,新增命令时不需要修改原有代码。
    • 缺点
      • 命令类的数量可能会增多,增加系统的复杂性。
      • 每个命令类都需要实现相同的接口,可能会导致代码冗余。
  3. 解释器模式 (Interpreter Pattern)

    • 优点
      • 可以解析和执行简单的语言或表达式。
      • 提供了灵活的扩展机制。
    • 缺点
      • 解释器模式的性能较差,不适合复杂的解析任务。
      • 代码量较大,增加了系统的复杂性。
  4. 迭代器模式 (Iterator Pattern)

    • 优点
      • 提供了一种统一的遍历集合的方式,隐藏了集合的内部结构。
      • 提高了代码的可读性和可维护性。
    • 缺点
      • 迭代器的引入会增加系统的复杂性。
      • 某些情况下,迭代器的使用可能会导致性能下降。
  5. 中介者模式 (Mediator Pattern)

    • 优点
      • 用一个中介对象来封装一系列的对象交互,降低了对象之间的耦合度。
      • 提高了系统的可维护性和可扩展性。
    • 缺点
      • 中介者类可能会变得非常复杂,需要谨慎设计。
      • 过多的中介者类会增加系统的复杂性。
  6. 备忘录模式 (Memento Pattern)

    • 优点
      • 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
      • 提供了撤销操作的支持。
    • 缺点
      • 备忘录对象可能会占用大量的内存,特别是在状态复杂的情况下。
      • 备忘录模式的实现可能会比较复杂。
  7. 观察者模式 (Observer Pattern)

    • 优点
      • 定义对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。
      • 提供了订阅和发布机制,提高了系统的灵活性。
    • 缺点
      • 观察者的数量可能会增多,导致性能下降。
      • 过多的观察者可能会导致系统结构混乱。
  8. 状态模式 (State Pattern)

    • 优点
      • 允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。
      • 提高了代码的可读性和可维护性。
    • 缺点
      • 状态类的数量可能会增多,增加系统的复杂性。
      • 状态转换的逻辑可能会比较复杂,需要谨慎设计。
  9. 策略模式 (Strategy Pattern)

    • 优点
      • 定义了一系列算法,把它们一个个封装起来,并且使它们可以互相替换。
      • 提高了代码的可读性和可维护性。
    • 缺点
      • 策略类的数量可能会增多,增加系统的复杂性。
      • 每个策略类都需要实现相同的接口,可能会导致代码冗余。
  10. 模板方法模式 (Template Method Pattern)

    • 优点
      • 定义了一个操作中的算法骨架,而将一些步骤延迟到子类中。
      • 提高了代码的可读性和可维护性。
    • 缺点
      • 子类的实现可能会受到父类的限制,灵活性降低。
      • 父类的修改可能会影响到所有的子类。
  11. 访问者模式 (Visitor Pattern)

    • 优点
      • 表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作。
      • 提高了代码的可读性和可维护性。
    • 缺点
      • 访问者类的数量可能会增多,增加系统的复杂性。
      • 如果对象结构经常变化,访问者模式的维护成本会很高。


原文地址:https://blog.csdn.net/xiaozukun/article/details/144350857

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!