探索设计模式:从组合到享元的软件架构之旅 (软件设计师笔记)

news2024/11/24 9:22:45

😀前言
设计模式是软件开发中常见和经常使用的一种最佳实践方式,它们是为了解决在软件设计中反复出现的一类问题而提出的通用解决方案。本文主要探讨了四种设计模式:Composite(组合)、Decorator(装饰器)、Facade(外观)和 Flyweight(享元)。这些模式分别对应不同的应用场景和解决的核心问题,它们各自具有其独特性和适用场景。

🏠个人主页:尘觉主页
在这里插入图片描述

🧑个人简介:大家好,我是尘觉,希望我的文章可以帮助到大家,您的满意是我的动力😉😉

在csdn获奖荣誉: 🏆csdn城市之星2名
⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ 💓Java全栈群星计划top前5
⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ 🤗 端午大礼包获得者
⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ 🥰阿里云专家博主
⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ 😉亚马逊DyamoDB结营

💕欢迎大家:这里是CSDN,我总结知识的地方,欢迎来到我的博客,感谢大家的观看🥰
如果文章有什么需要改进的地方还请大佬不吝赐教 先在次感谢啦😊

文章目录

  • 第七章 面向对象技术 补充-下
    • 结构型设计模式(7种)
      • 1. Adapter(适配器)
      • 🔺2. Bridge(桥接)
      • 🔺3. Composite(组合)
      • 4. Decorator(装饰器)
      • 5. Facade(外观)
      • 6. Flyweight(享元)
    • 😄总结

第七章 面向对象技术 补充-下

结构型设计模式(7种)

1. Adapter(适配器)

1)意图

将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

2)结构

其中:

  • Target定义Client使用的与特定领域相关的接口。
  • Client与符合Target接口的对象协同。
  • Adaptee定义一个已经存在的接口,这个接口需要适配。
  • Adapter对Adaptee的接口与Target接口进行适配。
/**
 * 适配器模式
 */
public class AdapterPattern {
    public static void main(String[] args) {
        Target target = new Adapter();
        target.Request();
    }
}

class Target{
    public void Request(){
        System.out.println("普通请求~");
    }
}

/**
 * 适配器
 */
class Adapter extends Target {
    private Adaptee adaptee = new Adaptee();
    @Override
    public void Request() {
        adaptee.SpecificRequest();
    }
}

class Adaptee{
    public void SpecificRequest(){
        System.out.println("特殊请求~");
    }
}

3)适用性

Adapter 模式适用于:

  • 想使用一个已经存在的类,而它的接口不符合要求。
  • 想创建一个可以服用的类,该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作。(了解)
  • (仅适用于对象Adapter)想使用一个已经存在的子类,但是不可能对每一个都进行子
    类化以匹配它们的接口。对象适配器可以适配它的父类接口。(了解)

🔺2. Bridge(桥接)

1)意图

将抽象部分与其实现部分分离,使它们都可以独立地变化。

2)结构

/**
 * 桥接模式
 */
public class BridgePattern {
    public static void main(String[] args) {
        Product productA = new ProductA();
        Product productB = new ProductA();

        Color red = new Red();
        productA.setName("产品A");
        productA.setColor(red);
        productA.Operation();

        Blue blue = new Blue();
        productB.setName("产品B");
        productB.setColor(blue);
        productB.Operation();
    }
}

abstract class Product{
    private String name;
    protected Color color;

    public void setName(String name){
        this.name = name;
    }

    public String getName(){
        return name;
    }

    public void setColor(Color color){
        this.color = color;
    }

    public abstract void Operation();
}

interface Color{
    void OperationImpl(String name);
}

class ProductA extends Product{

    @Override
    public void Operation() {
        color.OperationImpl(this.getName());
    }
}

class Red implements Color{

    @Override
    public void OperationImpl(String name) {
        System.out.println(name + ": 红色" );
    }
}

class Blue implements Color{

    @Override
    public void OperationImpl(String name) {
        System.out.println(name + ": 蓝色" );
    }
}

3)适用性(了解)

Bridge 模式适用于:

不希望在抽象和它的实现部分之间有一个固定的绑定关系。
类的抽象以及它的实现都应该可以通过生成子类的方法加以扩充。
对一个抽象的实现部分的修改应对客户不产生影响,即客户代码不必重新编译。
(C++)想对客户完全隐藏抽象的实现部分。
有许多类要生成的类层次结构。
想在多个对象间共享实现(可能使用引用计数),但同时要求客户并不知道这一点。

🔺3. Composite(组合)

1)意图

将对象组合成树型结构以表示“部分-整体”的层次结构。Composite 使得用户对单个对象
和组合对象的使用具有一致性。

2)结构

	<img src="https://picgoowyx.oss-cn-guangzhou.aliyuncs.com/imags/202309210851620.png" style="zoom: 67%;" />

其中:

  • Component 为组合中的对像声明接口:在适当情况下实现所有类共有接口的默认行为:
    声明一个接口用于访问和管理 Component 的子组件;(可选)在递归结构中定义一个
    接口,用于访问一个父组件,并在合适的情况下实现它。
  • Leaf 在组合中表示叶结点对象,叶结点没有子结点;在组合中定义图元对象的行为。
  • Composite定义有子组件的那些组件的行为;存储子组件;在Component接口中实现
    与子组件有关的操作。
  • Client 通过 Component 接口操纵组合组件的对象。
import java.util.*;

/**
 * 组合模式
 */
public class CompositePattern {
    public static void main(String[] args) {
        // 父类名 对象名 = new 子类名();
        AbstractFile root = new Folder("root");

        AbstractFile folderA = new Folder("folderA");
        AbstractFile folderB = new Folder("folderB");

        AbstractFile fileC = new File("fileC");
        AbstractFile fileD = new File("fileD");
        AbstractFile fileE = new File("fileE");

        root.Add(folderA);
        root.Add(folderB);
        root.Add(fileC);

        folderA.Add(fileD);
        folderA.Add(fileE);

        print(root);
    }

    static void print(AbstractFile file){
        file.printName();

        List<AbstractFile> childrenList = file.getChildren();
        if (childrenList == null){
            return;
        }

        for (AbstractFile children : childrenList) {
            print(children);
        }
    }
}

abstract class AbstractFile{
    protected String name;

    public void printName(){
        System.out.println(name);
    }

    public abstract boolean Add(AbstractFile file);
    public abstract boolean Remove(AbstractFile file);
    public abstract List<AbstractFile> getChildren();

}

class Folder extends AbstractFile {

    private List<AbstractFile> childrenList = new ArrayList<>();

    public Folder(String name) {
        this.name = name;
    }

    @Override
    public boolean Add(AbstractFile file) {
        return childrenList.add(file);
    }

    @Override
    public boolean Remove(AbstractFile file) {
        return childrenList.remove(file);
    }

    @Override
    public List<AbstractFile> getChildren() {
        return childrenList;
    }
}

class File extends AbstractFile{
    public File(String name) {
        this.name = name;
    }

    @Override
    public boolean Add(AbstractFile filei) {
        return false;
    }

    @Override
    public boolean Remove(AbstractFile file) {
        return false;
    }

    @Override
    public List<AbstractFile> getChildren() {
        return null;
    }
}

3)适用性

Composite 模式下适用于:

  • 想表示对象的部分-整体层次结构。
  • 希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。

4. Decorator(装饰器)

1)意图

动态地给一个对象添加一些额外的职责。就增加功能而言,Decorator模式比生成子类更加
灵活。

2)结构

其中:

  • Component定义一个对象接口,可以给这些对象动态地添加职责。
  • ConcreteComponent定义一个对象,可以给这个对象添加一些职责。
  • Decorator 维持一个指向 Component 对象的指针,并定义一个与Component 接口一致的接口。
  • ConcreteDecorator 向组件添加职责。
/**
 * 装饰器模式
 */
public class DecoratorPattern {
    public static void main(String[] args) {
        Person zhangsan = new Student("张三");
        zhangsan = new DecoratorA(zhangsan);
        zhangsan = new DecoratorB(zhangsan);
        zhangsan.Operation();

        System.out.println("==========分割线==============");

        // 对像链
        Person lisi = new DecoratorB(new DecoratorA(new Student("李四")));
        lisi.Operation();

    }
}

abstract class Decorator extends Person{
    protected Person person;
}

class DecoratorA extends Decorator{
    public DecoratorA(Person person){
        this.person = person;
    }

    @Override
    public void Operation() { // 职责
        person.Operation(); // 原本的职责
        System.out.println("写作业~");
    }
}

class DecoratorB extends Decorator{
    public DecoratorB(Person person){
        this.person = person;
    }

    @Override
    public void Operation() { // 职责
        person.Operation(); // 原本的职责
        System.out.println("考试~");
    }
}

abstract class Person{
    protected String name;

    public abstract void Operation(); // 职责

}

class Student extends Person{
    public Student(String name){
        this.name = name;
    }

    @Override
    public void Operation() {
        System.out.println(name + "的职责:学习~");
    }
}

3)适用性

Decorator 模式适用于:

  • 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
  • 处理那些可以撤销的职责。
  • 当不能采用生成子类的方式进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是,由于类定义被隐藏,或类定义不能用于生成子类。(了解)

5. Facade(外观)

1)意图

为子系统中的一组接口提供一个一致的界面,Facade 模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

2)结构

其中:

  • Facade知道哪些子系统类负责处理请求;将客户的请求代理给适当的子系统对象。
  • Subsystem classes实现子系统的功能;处理有Facade对象指派的任务;没有Facade的
    任何相关信息,即没有指向Facade的指针。
import java.util.Scanner;

/**
Facade(外观)
 */
public class FacadePattern {
    public static void main(String[] args) {
        Facade facade = new Facade();

        facade.methodA();
        facade.methodB();
        facade.methodC();
    }
}

class Facade{
    SubSystemOne subSystemOne;
    SubSystemTwo subSystemTwo;
    SubSystemThree subSystemThree;

    public Facade(){
        subSystemOne = new SubSystemOne();
        subSystemTwo = new SubSystemTwo();
        subSystemThree = new SubSystemThree();
    }

    public void methodA(){
        subSystemOne.methodOne();
    }

    public void methodB(){
        subSystemTwo.methodTwo();
    }

    public void methodC(){
        subSystemThree.methodThree();
    }
}

class SubSystemOne{
    public void methodOne(){
        System.out.println("执行子系统一的功能~");
    }
}

class SubSystemTwo{
    public void methodTwo(){
        System.out.println("执行子系统二的功能~");
    }
}

class SubSystemThree{
    public void methodThree(){
        System.out.println("执行子系统三的功能~");
    }
}

3)适用性

Facade 模式适用于:

  • 要为一个复杂子系统提供一个简单接口时。
  • 客户程序与抽象类的实现部分之间存在着很大的依赖性。
  • 当需要构建一个层次结构的子系统时,使用 Facade 模式定义子系统中每层的入口点。

6. Flyweight(享元)

1)意图

运用共享技术有效地支持大量细粒度的对象。

2)结构

	<img src="https://picgoowyx.oss-cn-guangzhou.aliyuncs.com/imags/202309210851623.png" style="zoom:67%;" />

其中:

  • Flyweight 描述一个接口,通过这个接口 Flyweight 可以接受并作用于外部状态。
  • ConcreteFlyweight 实现Flyweight接口,并为内部状态(如果有)增加存储空间。
  • ConcreteFlyweight 对象必须是可共享的。它所存储的状态必须是内部的,即它必须独
    立于 ConcreteFlyweight 对象的场景。
  • 并非所有的 Flyweight 子类都需要被共享。Flyweight 接口使共享成为可能,但它并不
    强制共享。在 Flyweight 对象结构的某些层次,UnsharedConcreteFlyweight 对象通常将
    ConcreteFlyweight 对象作为子结点。
  • FlyweightFactory 创建并管理Flyweight对象;确保合理地共享Flyweight,当用户请求
    一个Flyweight时,FlyweightFactory 对象提供一个已创建的实例或者在不存在时创建
    个实例。
  • Client 维持一个对 Flyweight 的引用;计算或存储一个或多个 Flyweight 的外部状态。
/**
 * 享元模式 案例1
 */

public class FlyweightPattern {
    public static void main(String[] args) {
        PieceFactory factory = new PieceFactory();

        Piece whitePiece1 = factory.getPiece(0);
        whitePiece1.draw(66,87);
        System.out.println(whitePiece1);

        Piece blackPiece1 = factory.getPiece(1);
        blackPiece1.draw(20,11);
        System.out.println(blackPiece1);

        Piece whitePiece2 = factory.getPiece(0);
        whitePiece1.draw(26, 54);
        System.out.println(whitePiece2);

        Piece blackPiece2 = factory.getPiece(1);
        blackPiece2.draw(12, 34);
        System.out.println(blackPiece2);
    }
}

😄总结

设计模式提供了一种结构化的方法来处理常见的设计问题,从而提高代码的可读性、可重用性和可维护性。通过上述模式的介绍和示例,我们可以看到它们是如何在实际情况中应用的。例如,Composite 模式可以帮助我们表示对象的层次结构,Decorator 模式允许我们动态地添加功能,Facade 模式提供了一个统一的接口来简化复杂系统,而 Flyweight 模式则通过共享技术来有效地支持大量的细粒度对象。当正确使用时,这些模式可以大大增强我们的代码质量和开发效率。

😁热门专栏推荐
想学习vue的可以看看这个

java基础合集

数据库合集

redis合集

nginx合集

linux合集

手写机制

微服务组件

spring_尘觉

springMVC

mybits

等等等还有许多优秀的合集在主页等着大家的光顾感谢大家的支持

🤔欢迎大家加入我的社区 尘觉社区

文章到这里就结束了,如果有什么疑问的地方请指出,诸佬们一起来评论区一起讨论😁
希望能和诸佬们一起努力,今后我们一起观看感谢您的阅读🍻
如果帮助到您不妨3连支持一下,创造不易您们的支持是我的动力🤞

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1050062.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Passper for Excel v3.7.3.4 Excel 密码恢复工具

网盘下载 Passper for Excel 是 Windows 上一款 Excel 密码恢复工具。可以恢复任何丢失或忘记的 Excel 文档密码。具有高恢复率和 100% 的数据安全性。支持通过 GPU 加速恢复密码&#xff0c;恢复速度提高 10 倍以上。 字典&#xff0c;根据内置或自定义词典恢复密码。 一般来…

【接口测试】测试基础

一、接口测试简介 1.接口测试的定义 接口测试是一种测试系统组件间接口的测试&#xff0c;主要目标是检测外部系统与系统之间以及内部各个子系统之间的交互点&#xff0c;以检查数据的交换、传递和控制管理过程&#xff0c;以及系统间的相互逻辑依赖关系等。 随着前后端分离…

Visio如何对文本打下标、上标,以及插入公式编辑器等问题(已解决)

解决这个问题的本质问题&#xff0c;就是在Visio中插入公式编辑器&#xff08;这不是visio的常用命令&#xff0c;需要添加&#xff09;。 打开Visio--》文件--选项 点击选项&#xff0c;弹出对话框。在自定义功能区中&#xff0c;点击 常用命令&#xff0c;在下拉选项中&#…

【Ambari】银河麒麟V10 ARM64架构_安装Ambari2.7.6HDP3.3.1问题总结

&#x1f341; 博主 "开着拖拉机回家"带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——&#x1f390;开着拖拉机回家_大数据运维-CSDN博客 &#x1f390;✨&#x1f341; &#x1fa81;&#x1f341; 希望本文能够给您带来一定的帮助&#x1f338;文…

IDEA Debug技巧大全,看完就能提升工作效率

作者简介 目录 1.行断点 2.方法断点 3.异常断点 4.字段断点 5.条件表达式 1.行断点 行断点就是平时我们在代码行旁边单击鼠标打上的断点&#xff0c;这个没有什么好说的。关键点在于很多人不知道的&#xff0c;行断点其实是可以右击选择是对改行的全部调用都生效&#xf…

如何在Proteus进行STM32F103C8T6模拟以及keil5开发

一、下载Proteus 8和keil5 最新版 Proteus 8.15 Professional 图文安装教程&#xff08;附安装包&#xff09;_proteus密钥_main工作室的博客-CSDN博客Keil uVision5 5.38官方下载、安装及注册教程_keil uvision5下载_这是乐某的博客-CSDN博客 二、新建STM32F103C8项目 接下来…

计算协方差矩阵df.cov()

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 计算协方差矩阵 df.cov() [太阳]选择题 下列选项对代码运行结果描述错误的是&#xff1f; import pandas as pd df pd.DataFrame({ A: [1, 2, 3, 4, 5], B: [5, 4, 3, 2, 1] }) prin…

二维码智慧门牌管理系统:智能生活的新选择

文章目录 前言一、地址的唯一性与规范性二、智能化生活三、智能家居的融合四、广泛的应用场景 前言 在科技飞速发展的今天&#xff0c;智能化已经渗透到我们生活的各个层面。而在我们日常生活中&#xff0c;门牌号码的识别和管理是一个看似平凡但却非常重要的环节。为了更好地…

源码编译安装pkg-config

安装环境&#xff1a;银河麒麟 1 到这个网址下载pkg-config源码&#xff1a; Index of /releases (pkg-config.freedesktop.org) 2 解压 3 进入解压后的目录。输入 ./configure 但是报错。 4 根据报错信息&#xff0c;将configure改为&#xff1a; ./configure --with-i…

怒刷LeetCode的第19天(Java版)

目录 第一题 题目来源 题目内容 解决方法 方法一&#xff1a;遍历一次数组 方法二&#xff1a;贪心算法 方法三&#xff1a;双指针 第二题 题目来源 题目内容 解决方法 方法一&#xff1a;动态规划 方法二&#xff1a;贪婪算法 方法三&#xff1a;正则表达式 第…

基础算法--KMP字符串

KMP 算法是一个快速查找匹配串的算法&#xff0c;它的作用其实就是本题问题&#xff1a;如何快速在「原字符串」中找到「匹配字符串」。 在朴素解法中&#xff0c;不考虑剪枝的话复杂度是 O(m∗n) 的&#xff0c;而 KMP 算法的复杂度为 O(mn)。 KMP 之所以能够在O(mn) 复杂度内…

成都优优聚公司是靠谱的吗?

成都优优聚公司专业美团代运营团队&#xff0c;以高效、专业、全面的服务赢得了众多客户的青睐。作为一家在美团代运营行业具备丰富经验和优质资源的公司&#xff0c;我们始终以客户的需求为导向&#xff0c;致力于为客户打造出色的美团线上运营方案。 我们公司拥有一支经验丰富…

设计模式探索:从理论到实践的编码示例 (软件设计师笔记)

&#x1f600;前言 设计模式&#xff0c;作为软件工程领域的核心概念之一&#xff0c;向我们展示了开发过程中面对的典型问题的经典解决方案。这些模式不仅帮助开发者创建更加结构化、模块化和可维护的代码&#xff0c;而且也促进了代码的复用性。通过这篇文章&#xff0c;我们…

处理不平衡数据的十大Python库

数据不平衡是机器学习中一个常见的挑战&#xff0c;其中一个类的数量明显超过其他类&#xff0c;这可能导致有偏见的模型和较差的泛化。有各种Python库来帮助有效地处理不平衡数据。在本文中&#xff0c;我们将介绍用于处理机器学习中不平衡数据的十大Python库&#xff0c;并为…

面向对象之旅:核心理念、设计方法与UML详解(软件设计师笔记)

&#x1f600;前言 面向对象技术是现代软件工程的核心&#xff0c;为软件设计和开发带来了一种强大且有序的方法。通过将现实世界的实体和概念映射到可操作的代码结构&#xff0c;该技术使我们能够更高效、清晰和可靠地创建复杂的软件系统。在本章中&#xff0c;我们将详细介绍…

我的国庆回家之路

文章目录 回家的计划假期的礼物学习新技术与家人团聚遇到的趣事总结 &#x1f389;欢迎来到IT陈寒的博客空间~我的国庆回家之路 ☆* o(≧▽≦)o *☆嗨~我是IT陈寒&#x1f379;✨博客主页&#xff1a;IT陈寒的博客&#x1f388;该系列文章专栏&#xff1a;Java学习路线&#x1…

【运维日常】华为云专线实现idc通过nat出网

本站以分享各种运维经验和运维所需要的技能为主 《python零基础入门》&#xff1a;python零基础入门学习 《python运维脚本》&#xff1a; python运维脚本实践 《shell》&#xff1a;shell学习 《terraform》持续更新中&#xff1a;terraform_Aws学习零基础入门到最佳实战 《k8…

【VUE复习·9】v-for 基础用法(循环渲染也叫列表渲染)

总览 1.v-for 都能循环什么 2.用法 一、v-for 都能遍历什么 能循环的东西包括&#xff1a;数组、对象、字符串&#xff08;和java里面的3个引用数据类型一样&#xff09;、纯粹循环数量&#xff08;少用&#xff09; 二、用法 1.用法1&#xff1a;简单循环&#xff08;遍历…

开源协作开发者内容平台Vrite

什么是 Vrite &#xff1f; Vrite 是一个开源协作空间&#xff0c;用于创建、管理和部署产品文档、技术博客和知识库。它旨在提供高质量、集成的用户和开发人员体验。 Vrite 具有以下功能&#xff1a; 内置管理仪表板&#xff0c;用于使用看板或列表视图管理内容生产和交付&am…

亘古难题:前端开发 or 后端开发

目录 一、引言二、两者的对比分析1. 技能要求和专业知识前端开发后端开发 2. 职责和工作内容前端开发后端开发 3. 项目类型和应用领域前端开发后端开发 4. 就业前景和市场需求前端开发后端开发 三、技能转换和跨领域工作四、介绍全栈开发五、结语附、开源项目微服务商城项目前后…