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

前言
设计模式是软件开发中常见和经常使用的一种最佳实践方式,它们是为了解决在软件设计中反复出现的一类问题而提出的通用解决方案。本文主要探讨了四种设计模式: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)结构

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

其中:

  • 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)结构

探索设计模式:从组合到享元的软件架构之旅 (软件设计师笔记)_第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)结构

	

其中:

  • 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)结构

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

其中:

  • 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)结构

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

其中:

  • 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)结构

	

其中:

  • 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连支持一下,创造不易您们的支持是我的动力

你可能感兴趣的:(设计模式,笔记)