图解软件设计模式

就这一次!用23张图详解设计模式,把设计模式给你分析透彻 设计模式可以分为下面三大类: 创建型 1. Factory Method(工厂方法) 2. Abstract Factory(抽象工厂) 3. Builder(建造者) 4. Prototype(原型) 5. Singleton(单例) 结构型 6. Adapter Class/Object(适配器) 7. Bridge(桥接) 8. Composite(组合) 9. Decorator(装饰) 10. Facade(外观) 11. Flyweight(享元) 12. Proxy( 阅读详情

参考资料

1、图解设计模式 -----【日】结城浩 著
2、尚硅谷java设计模式网课

软件设计模式七大设计原则

单一职责原则

基本介绍

对类来说的,即一个类应该只负责一项职责。如类A负责两个不同职责:职责1,职责2。当职责1需求变更而改变A是,可能造成职责2执行错误,所以需要将类A的粒度分解为A1,A2

注意事项和细节:

1、降低类的复杂度,一个类只负责一项职责。
2、提高类的可读性,可维护性
3、降低变更引起的风险
4、通常情况下,我们应当遵守单一职责原则,只有逻辑足等简单,才可以在代码级违反单一职责原则;只有类中方法数量足够少,可以在方法级别保持单一职责原则

接口隔离原则

基本介绍

客户端不应该依赖它不需要的接口,即一个类通过接口去依赖另一个类,所依赖的接口应该是最小的接口

实例:

在这里插入图片描述

使用接口隔离原则改进:

在这里插入图片描述

依赖倒转原则

基本介绍
1)高层模块不应该依赖低层模块,二者都应该依赖其抽象

2)抽象不应该依赖细节,细节应该依赖抽象

3)依赖倒转(倒置)的中心思想是面向接口编程

4)依赖倒转原则是基于这样的设计理念:相对于细节的多变性,抽象的东西要稳定的多。以抽象为基础搭建的架构比以细节为基础的架构要稳定的多。在java中,抽象指的是接口或抽象类,细节就是具体的实现类

5)使用接口或抽象类的目的是制定好规范,而不涉及任何具体的操作,把展现细节的任务交给他们的实现类去完成

里氏替换原则

基本介绍

如果对每个类型为T1的对o1,都有类型为T2的对象o2,使得以T1定义的所有程序P在所有的对象o1都代换成o2时,程序P的行为没有发生变化,那么类型T2是类型T1的子类型。换句话说,所有引用基类的地方必须能透明地使用其子类的对象。

在使用继承时,遵循里氏替换原则,在子类中尽量不要重写父类的方法

里氏替换原则告诉我们,继承实际上让两个类耦合性增强了,在适当的情况下,原来的父类和子类都继承一个更通俗的基类,采用聚合,组合,依赖等关系替代

开闭原则

基本介绍

1)开闭原则(Open Closed Principle)是编程中最基础、最重要的设计原则

2)一个软件实体如类,模块和函数应该对扩展开放(对提供方),对修改关闭(对使用方)。用抽象构建框架,用实现扩展细节。

3)当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化。

4)编程中遵循其它原则,以及使用设计模式的目的就是遵循开闭原则。

案例

方案1:

在这里插入图片描述
在这里插入图片描述

方案1优缺点:
1)优点是比较好理解,简单易操作。
2)缺点是违反了设计模式的ocp原则,即对扩展开放(提供方),对修改关闭(使用方)。
即当我们给类增加新功能的时候,尽量不修改代码,或者尽可能少修改代码.
3)比如我们这时要新增加一个图形种类三角形,我们需要修改的地方较多

方案2:

把创建Shape类做成抽象类,并提供一个抽象的draw方法,让子类去实现即可,这样我们有新的图形种类时,只需要让新的图形类继承Shape,并实现draw方法即可,使用方的代码就不需要修改->满足了开闭原则

迪米特法则

基本介绍

1)一个对象应该对其他对象保持最少的了解

2)类与类关系越密切,耦合度越大

3)迪米特法则(Demeter Principle)又叫最少知道原则,即一个类对自己依赖的类知道的越少越好。也就是说,对于被依赖的类不管多么复杂,都尽量将逻辑封装在类的内部。对外除了提供的public 方法,不对外泄露任何信息

4)迪米特法则还有个更简单的定义:只与直接的朋友通信

5)直接的朋友:每个对象都会与其他对象有耦合关系,只要两个对象之间有耦合关系,我们就说这两个对象之间是朋友关系。耦合的方式很多,依赖,关联,组合,聚合等。其中,我们称出现成员变量,方法参数,方法返回值中的类为直接的朋友,而出现在局部变量中的类不是直接的朋友。也就是说,陌生的类最好不要以局部变量的形式出现在类的内部。

迪米特法则注意事项和细节

1)迪米特法则的核心是降低类之间的耦合

2)但是注意:由于每个类都减少了不必要的依赖,因此迪米特法则只是要求降低类间(对象间)耦合关系,并不是要求完全没有依赖关系

合成复用原则

基本介绍

原则是尽量使用合成/聚合的方式,而不是使用继承

实例:
在这里插入图片描述

UML类图

类图—依赖关系

只要是在类中用到了对方,那么他们之间就存在依赖关系。如果没有对方,连编绎都通过不了。

public class PersonServiceBean{
	private PersonDao personDao;//类
	public void save(Person person){}
	public IDCard getlDCard(Integer personid){}
	public void modify(){
		Department department=new Department();
	}
}
public class PersonDao{}
public class IDCard{}
public class Person{}
public class DFpartment{}

在这里插入图片描述

类图—泛化关系

泛化关系实际上就是继承关系,他是依赖关系的特例

public abstract class DaoSupport{
    public void save(Object entity){}
    public void delete(Object id){}
}
public class PersonServiceBean extends Daosupport{
}

在这里插入图片描述

类图—实现关系

实现关系实际上就是A类实现B类(接口),他是依赖关系的特例

public interface PersonService{
	public void delete(Interger id);

}

public class PersonServiceBean implements PersonService{

	public void delete(Interger id){}

}

在这里插入图片描述

类图—聚合关系

聚合关系表示的是整体和部分的关系,整体和部分可以分开

public class Computer{
    private Mouse mouse;
    private Moniter moniter;
    public void setMouse(Mouse mouse){
        this.mouse=mouse;
       
    }
    public void setMonitor(Moniter moniter){
        this.moniter=moniter;
    }
}

在这里插入图片描述

类图—组合关系

组合关系表示的也是整体和部分的关系,但是整体和部分不可以分开

如果我们认为Mouse,Monitor和Computer是不可分离的,则升级为组合关系

public class Computer{
    private Mouse mouse = new Mouse();
    private Moniter moniter = new Moniter();
    
}

在这里插入图片描述

23个设计模式

迭代器模式(Iterator)

Iterator模式用于在数据集合中按照顺序遍历集合。

在这里插入图片描述
lterator(迭代器)
该角色负责定义按顺序逐个遍历元素的接口(API)。

Concretelterator(具体的迭代器)
该角色负责实现Iterator角色所定义的接口(API)。

Aggregate(集合)
该角色负责定义创建Iterator角色的接口(API)。这个接口(API)是一个方法,会创建出“按顺序访问保存在我内部元素的人”。

ConcreteAggregate(具体的集合)
该角色负责实现Aggregate角色所定义的接口(API)。它会创建出具体的Iterator角色,即Concretelterator角色。

适配器模式(Adapter)

适配器用于填补需求和实际情况的空白,当我们不是从空白开始编程,需要对原有接口重复利用时,可以利用适配器模式,它可以很方便地利用原有接口创建新的接口。
适配器有两种方式: ①类适配器模式(使用继承的适配器)②对象适配器模式(使用委托的适配器)

类适配器模式的类图
在这里插入图片描述
对象适配器模式的类图
在这里插入图片描述
Target(对象)
该角色负责定义所需的方法。

Client(请求者)
该角色负责使用Target角色所定义的方法进行具体处理。

Adaptee(被适配)
注意不是Adapt-er(适配)角色,而是Adapt-ee(被适配)角色。Adaptee是一个持有既定方法的角色。如果Adaptee角色中的方法与Target角色的方法相同,就不需要接下来的Adapter角色了。

Adapter(适配)
Adapter模式的主人公。使用Adaptee角色的方法来满足Target角色的需求,这是Adapter模式的目的,也是Adapter角色的作用。

在类适配器模式中,Adapter角色通过继承来使用Adaptee角色,而在对象适配器模式中,Adapter角色通过委托来使用Adaptee角色。

模板方法模式(Template Method)

Template Method模式是带有模板功能的模式,组成模板的方法被定义在父类中。由于这些方法是抽象方法,所以只查看父类的代码是无法知道这些方法最终会进行何种具体处理的,唯一能知道的就是父类是如何调用这些方法的。

实现上述这些抽象方法的是子类。在子类中实现了抽象方法也就决定了具体的处理。也就是说,只要在不同的子类中实现不同的具体处理,当父类的模板方法被调用时程序行为也会不同。但是,不论子类中的具体实现如何,处理的流程都会按照父类中所定义的那样进行。

像这样在父类中定义处理流程的框架,在子类中实现具体处理的模式成为Template Method模式。

在这里插入图片描述
AbstractClass(抽象类)
AbstractClass角色不仅负责实现模板方法,还负责声明在模板方法中所使用到的抽象方法。这些抽象方法由子类ConcreteClass角色负责实现。

ConcreteClass(具体类)
该角色负责具体实现AbstractClass角色中定义的抽象方法。这里实现的方法将会在AbstractClass角色的模板方法中被调用。

工厂方法模式(Factory Method)

在Factory Method模式中,父类决定实例的生成方式,但并不决定所要生成的具体的类,具体的处理全部交给子类负责。这样就可以将生成实例的框架(framework)和实际负责生成实例的类解耦。
在这里插入图片描述
Product(产品)
Product角色属于框架这一方,是一个抽象类。它定义了在Factory Method模式中生成的那些实例所持有的接口(API),但具体的处理则由子类ConcreteProduct角色决定。

Creator(创建者)

Creator角色属于框架这一方,它是负责生成Product角色的抽象类,但具体的处理则由子类ConcreteCreator角色决定。

Creator 角色对于实际负责生成实例的ConcreteCreator角色一无所知,它唯一知道的就是,只要调用Product角色和生成实例的方法(图中的factoryMethod方法),就可以生成Product的实例。不用new关键字来生成实例,而是调用生成实例的专用方法来生成实例,这样就可以防止父类与其他具体类耦合。

ConcreteProduct(具体的产品)
ConcreteProduct 角色属于具体加工这一方,它决定了具体的产品。

ConcreteCreator(具体的创建者)
ConcreteCreator角色属于具体加工这一方,它负责生成具体的产品。

单例模式(Singleton)

确保只生成一个实例的模式被称作Singleton模式。

Singleton类的构造函数是Private的,这是为了禁止从singleton类外部调用构造函数。如果从singleton类以外的代码中调用构造函数new singleton(),就会出现编译错误。
在这里插入图片描述
"-"表示private方法和字段;“+”表示public方法和字段;下划线表示static方法和字段

Singleton

在Singleton模式中,只有Singleton这一个角色。Singleton角色中有一个返回唯一实例的static方法。该方法总是会返回同一个实例。

原型模式(Prototype)

Prototype模式根据现有实例来生成新实例。

以下情况不能根据类来生成实例,而要根据现有的实例来生成新的实例,此时应使用原型模式对类进行复制:

① 对象种类繁多,无法将它们整合到一个类中;② 难以根据类生成实例;③ 想解耦框架与生成的实例时

在这里插入图片描述
Prototype(原型)

Product角色负责定义用于复制现有实例来生成新实例的方法。

ConcretePrototype(具体的原型)

ConcretePrototype角色负责实现复制现有实例并生成新实例的方法。

Client(使用者)

Client角色负责使用复制实例的方法生成新的实例。

在java中如果想要调用clone方法,被复制的类必须实现java.lang.Clonable这个标记接口。clone是浅复制,只是将复制实例的字段值直接复制到新的实例中,并不会调用被复制实例的构造函数。

建造者模式(Builder)

Builder模式用于组装具有复杂结构的实例

Builder模式的类图:
在这里插入图片描述
Builder模式的时序图:
在这里插入图片描述
Builder(建造者)

Builder角色负责定义用于生成实例的接口(API)。Builder角色中准备了用于生成实例的方法。

ConcreteBuilder(具体的建造者)

ConcreteBuilder角色是负责实现Builder角色的接口的类(API)。这里定义了在生成实例时实际被调用的方法。此外,在ConcreteBuilder角色中还定义了获取最终生成结果的方法。

Director(监工)

Director角色负责使用Builder角色的接口(API)来生成实例。它并不依赖于ConcreteBuilder角色。为了确保不论ConcreteBuilder角色是如何被定义的,Director角色都能正常工作,它只调用在Builder角色中被定义的方法。

Client(使用者)

该角色使用了Builder模式。

抽象工厂模式(Abstract Factory)

抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。

抽象工厂模式中的具体工厂不只是创建一种产品,它负责创建一族产品。当系统所提供的工厂生产的具体产品并不是一个简单的对象,而是多个位于不同产品等级结构、属于不同类型的同一族产品时就可以使用抽象工厂模式。
在这里插入图片描述
AbstractProduct(抽象产品)

AbstractProduct角色负责定义AbstractFactory角色所生成的抽象零件和产品的接口(API)。

AbstractFactory(抽象工厂)

AbstractFactory角色负责定义用于生成抽象产品的接口(API)。

Client(委托者)

Client角色仅会调用AbstractFactory角色和AbstractProduct角色的接口(API)来进行工作,对于具体的零件、产品和工厂一无所知。图中省略了该角色

ConcreteProduct(具体产品)

ConcreteProduct 角色负责实现AbstractProduct角色的接口(API)。

ConcreteFactory(具体工厂)

ConcreteFactory角色负责实现AbstractFactory角色的接口(API)

抽象工厂模式的优缺点:

①易于增加具体的工厂,用于生产新的产品族

在Abstract Factory模式中增加具体的工厂是非常容易的。这里说的“容易”指的是需要编写哪些类和需要实现哪些方法都非常清楚。这样一来,无论要增加多少个具体工厂(或是要修改具体工厂的Bug),都无需修改抽象工厂和Main部分。

②难以在一个产品族中增加新的产品

需要修改所有的工厂角色,包括抽象工厂类,在所有的工厂类中都需要增加生产新产品的方法,违背了开闭原则。

工厂模式对比

1、简单工厂模式:

定义了一个创建对象的类,由这个类来封装实例化对象的行为,即create方法。

简单工厂模式的类图
在这里插入图片描述
2、工厂方法模式:

定义了一个创建对象的抽象方法,由子类决定要实例化的类。工厂方法模式将对象的实例化推迟到子类。

3、抽象工厂模式:

① 定义了一个interface用于创建相关或有依赖关系的对象簇,而无需指明具体的类。

② 抽象工厂模式可以将简单工厂模式和工厂方法模式进行整合。

③抽象工厂模式将工厂抽象成两层:AbsFactory(抽象工厂)和具体实现的工厂子类,每个工厂子类可以生产一系列产品。

4、抽象工厂模式与工厂方法模式的对比:

①抽象工厂模式: 一个工厂可以生产一系列产品(一族产品),极大减少了工厂类的数量

②工厂方法模式: 每个具体工厂只有一个或者一组重载的工厂方法,只能生产一种产品,可能会导致系统中存在大量的工厂类,势必会增加系统的开销。

③当一个工厂等级结构可以创建出分属于不同产品等级结构的一个产品族中的所有对象时, 抽象工厂模式比工厂方法模式更为简单、更有效率

桥接模式(Bridge)

Bridge模式的作用是将类的功能层次结构和类的实现层次结构连接起来,即在“类的功能层次结构”和“类的实现层次结构”之间搭建桥梁。

类的功能层次结构:

假设现在有一个类Something。当我们想在something中增加新功能时(想增加一个具体方法时),会编写一个something类的子类(派生类),即SomethingGood类。这样就构成了一个小小的类层次结构。
在这里插入图片描述
父类具有基本功能
在子类中增加新的功能

以上这种层次结构被称为类的功能层次结构。
如果我们要继续在SomethingGood类的基础上增加新的功能,该怎么办呢?这时,我们可以同样地编写一个SomethingGood类的子类,即SomethingBetter类。这样,类的层次结构就加深了。
在这里插入图片描述
类的功能层次结构即对类进行纵向扩展,但是类的功能层次结构不应当过深。

类的实现层次结构:

当子类ConcreteClass实现了父类AbstractClass类的抽象方法时,它们之间就构成了一个小小的层次结构。
在这里插入图片描述
但是,这里的类的层次结构并非用于增加功能,也就是说,这种层次结构并非用于方便我们增加新的方法。它的真正作用是帮助我们实现下面这样的任务分担:

父类通过声明抽象方法来定义接口(APl)

子类通过实现具体方法来实现接口(APl)

这种层次结构被称为类的实现层次结构。

当我们以其他方式实现AbstractClass时,例如要实现一个AnotherConcreteClass时,类的层次结构会稍微发生一些变化。

在这里插入图片描述
为了一种新的实现方式,我们继承了AbstractClass的子类,并实现了其中的抽象方法。

类的实现层次结构即对类进行横向扩展。

Bridge模式类图:
在这里插入图片描述
Abstraction(抽象化)

该角色位于“类的功能层次结构”的最上层。它使用Implementor角色的方法定义了基本的功能。该角色中保存了Implementor角色的实例。

RefinedAbstraction(改善后的抽象化)

在Abstraction角色的基础上增加了新功能的角色。

Implementor(实现者)

该角色位于“类的实现层次结构”的最上层。它定义了用于实现Abstraction角色的接口(API)的方法。

Concretelmplementor(具体实现者)

该角色负责实现在Implementor角色中定义的接口(API)。

在类图中,左侧的两个类构成了“类的功能层次结构”,右侧两个类构成了“类的实现层次结构”。类的两个层次结构之间的桥梁是impl字段。

总结:

Bridge模式的特征是将“类的功能层次结构”与“类的实现层次结构”分离开了。将类的这两个层次结构分离开有利于独立地对它们进行扩展。

当想要增加功能时,只需要在“类的功能层次结构”一侧增加类即可,不必对“类的实现层次结构”做任何修改。而且,增加后的功能可以被“所有的实现”使用。

策略模式(Strategy)

策略模式能够整体地替换算法的实现部分,能让我们以不同的算法来解决同一个问题。
在这里插入图片描述
Strategy(策略)

Strategy角色负责决定实现策略所必需的接口(API)。

ConcreteStrategy(具体的策略)

ConcreteStrategy角色负责实现Strategy角色的接口(API),即负责实现具体的策略(战略、方向、方法和算法)。

Context(上下文)

负责使用Strategy角色。Context角色保存了ConcreteStrategy角色的实例,并使用ConcreteStrategy角色去实现需求(总之,还是要调用Strategy角色的接口(API))。

组合模式(Composite)

将容器和内容作为同一种东西看待,可以帮助我们方便地处理问题。在容器中既可以放入内容,又可以放入小容器,然后在那个小容器中又可以放入更小的容器。这样,就形成了容器结构、递归结构。
在这里插入图片描述
能够使容器与内容具有一致性,创造出递归结构(树形结构) 的模式就是Composite模式。
在这里插入图片描述
Leaf(树叶)

表示“内容”的角色。在该角色中不能放入其他对象。

Composite(复合物)

表示容器的角色。可以在其中放入Leaf角色和Composite角色。

Component

使Leaf角色和Composite角色具有一致性的角色。Composite角色是Leaf角色和Composite角色的父类。

Client

使用Composite模式的角色。

装饰者模式(Decorator)

装饰者模式:动态的将新功能附加到对象上。在对象功能扩展方面,它比继承更有弹性,装饰者模式也体现了开闭原则(ocp)。
在这里插入图片描述
Component
增加功能时的核心角色。Component角色只是定义了被装饰对象的接口(API)。

ConcreteComponent
该角色是实现了Component角色所定义的接口(API)的具体被装饰对象。

Decorator(装饰物)
该角色具有与Component角色相同的接口(API)。在它内部保存了被装饰对象Component角色。Decorator角色知道自己要装饰的对象。

ConcreteDecorator(具体的装饰物)
该角色是具体的Decorator角色。

访问者模式(Visitor)

1)访问者模式(Visitor Pattern),封装一些作用于某种数据结构的各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作。

2)主要将数据结构与数据操作分离,解决数据结构和操作耦合性问题

3)访问者模式的基本工作原理是:在被访问的类里面加一个对外提供接待访问者的接口(增加accept方法,参数是访问者visitor类)

4)访问者模式主要应用场景是:需要对一个对象结构中的对象进行很多不同操作(这些操作彼此没有关联),同时需要避免让这些操作“污染“这些对象的类,可以选用访问者模式解决
在这里插入图片描述
Visitor(访问者)
Visitor角色负责对数据结构中每个具体的元素(ConcreteElement角色)声明一个用于访问XXXXX的visit(XXXXX)方法。visit(XXXXX)是用于处理XXXXX的方法,负责实现该方法的是ConcreteVisitor角色。

ConcreteVisitor(具体的访问者)
ConcreteVisitor角色负责实现Visitor角色所定义的接口(API)。它要实现所有的visit(XXXXX)方法,即实现如何处理每个ConcreteElement角色。随着visit(XXXXX)处理的进行,ConcreteVisitor角色的内部状态也会不断地发生变化。

Element(元素)
Element角色表示Visitor角色的访问对象。它声明了接受访问者的accept方法。accept方法接收到的参数是Visitor角色。

ConcreteElement
ConcreteElement角色负责实现Element角色所定义的接口(API)。

ObjectStructure(对象结构)
ObjectStructur角色负责处理Element角色的集合。

访问者模式的缺点:(1) 具体元素对访问者公布细节,也就是说访问者关注了其他类的内部细节,这是迪米特法则所不建议的,这样造成了具体元素变更比较困难。(2) 违背了依赖倒转原则。访问者依赖的是具体元素,而不是抽象元素

职责链模式(Chain of Responsibility)

将多个对象组成一条职责链,然后按照它们在职责链上的顺序一个一个地找出到底应该谁来负责处理。

使用职责链模式可以弱化“请求方”和“处理方”之间的关联关系,让双方各自都成为可独立复用的组件。

使用职责链模式确实会导致处理请求发生了延迟;如果请求和处理者之间的关系是确定的,而且需要非常快的处理速度时,不使用职责链模式会更好。
在这里插入图片描述
Handler(处理者)

Handler角色定义了处理请求的接口(API)。Handler角色知道“下一个处理者”是谁,如果自己无法处理请求,它会将请求转给“下一个处理者”。当然,“下一个处理者”也是Handler角色。

ConcreteHandler(具体的处理者)

ConcreteVisitor角色是处理请求的具体角色。

Client(请求者)

Client角色是向第一个ConcreteHandler角色发送请求的角色。

外观模式(Facade)

外观模式的引入:一个影院管理项目

组件一个家庭影院:
DVD播放器、投影仪、自动屏幕、环绕立体声、爆米花机,要求完成使用家庭影院的功能,其过程为:
1、开爆米花机
2、放下屏幕
3、开投影仪
4、开音响
5、开DVD,选dvd
6、去拿爆米花
7、调暗灯光
8、播放
9、投影结束后,关闭各种设备

传统方式解决影院管理:
在这里插入图片描述
传统方式解决影院管理问题分析:

1)在ClientTest的main方法中,创建各个子系统的对象,并直接去调用子系统(对象)相关方法,会造成调用过程混乱,没有清晰的过程

2)不利于在ClientTest中,去维护对子系统的操作

3)解决思路:定义一个高层接口,给子系统中的一组接口提供一个一致的界面,用来访问子系统中的一群接口

4)也就是说通过定义一个一致的接口(界面类),用以屏蔽内部子系统的细节,使得调用端只需跟这个接口发生调用,而无需关系这个系统的内部细节 => 外观模式

外观模式基本介绍:
1)外观模式(Facade),也叫“过程模式”:外观模式为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口与使得这一子系统更加容易使用
2)外观模式通过定义一个一致的接口,用以屏蔽子系统的细节,使用调用端只需跟这个接口发生调用,而无需关系这个子系统的内部细节

外观模式类图:
在这里插入图片描述
Facade(窗口)

Facade角色是代表构成系统的许多角色的“简单窗口”。Facade角色向系统外部提供高层接口(API)。

构成系统的许多其他角色

这些角色各自完成自己的工作,它们并不知道Facade角色。Facade角色调用其他角色进行工作,但是其他角色不会调用Facade角色。这里是类图中的各个子系统,他们是功能的实际提供者。

Client(请求者)

Client角色负责调用Facade角色。

Facade模式可以让复杂的东西看起来简单,它使得接口(API)变少了,意味着程序与外部的关联关系弱化了,这样更容易使我们的包作为组件被复用。

中介者模式(Mediator)

基本介绍

  1. 中介者模式(Mediator Pattern),用一个中介对象来封装一系列的对象交互。中介者使各个对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

  2. 要调整多个对象之间的关系时,就需要用到Mediator模式了。即不让各个对象之间互相通信,而是增加了一个中介者角色,让他们各自与中介者通信,然后,将逻辑处理交给中介者负责。

类图
在这里插入图片描述
Mediator(仲裁者、中介者)

Mediator角色负责定义与Colleague角色进行通信和做出决定的接口(API)。

ConcreteMediator(具体的仲裁者、中介者)

ConcreteMediator角色负责实现Mediator角色的接口(API),负责实际做出决定。他需要知道所有具体的同事类,并接受某个同事对象消息,完成相应的任务。

Colleague(同事)

Colleague角色负责定义与Mediator角色进行通信的接口(API)。

ConcreteColleague(具体的同事)

ConcreteColleague角色负责实现Colleague角色的接口(API)。每个同事只知道自己的行为,而不了解其他同事类的行为,但是他们都依赖中介者对象。

中介者模式注意事项和细节:

1)多个类相互耦合,会形成网状结构,使用中介者模式将网状结构分离为星型结构,进行解耦

2)减少类间依赖,降低了耦合,符合迪米特原则

3)中介者承担了较多的责任,一旦中介者出现了问题,整个系统就会受到影响

4)如果设计不当,中介者对象本身变得过于复杂,这点在实际使用时,要特别注意

观察者模式(Observer)

在观察者模式中,当观察对象的状态发生变化时,会通知给观察者。观察者模式适用于根据对象状态进行相应处理的场景。
在这里插入图片描述
Subject(观察对象)

Subject角色表示观察对象。Subject角色定义了注册观察者(addObserver)和删除观察者(deleteObserver)的方法。此外,它还声明了“获取现在的状态”(getSubjectStatus)的方法。

ConcreteSubject(具体的观察对象)

ConcreteSubject角色表示具体的被观察对象。当自身状态发生变化后,它会通知所有已经注册的Observer角色(notifyObservers)。

Observer(观察者)

Observer角色负责接收来自Subject角色的状态变化的通知。为此,它声明了update方法。

ConcreteObserver(具体的观察者)

ConcreteObserver角色表示具体的Observer。当它的update方法被调用后,会去获取要观察的对象的最新状态。

备忘录模式(Memento)

备忘录模式(Memento Pattern) 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态.

备忘录模式事先将某个时间点的实例的状态保存下来,之后在有必要时,再将实例恢复至当时的状态。

在这里插入图片描述
Originator(生成者)

Originator角色会在保存自己的最新状态时生成Memento角色。当把以前保存的Memento角色传递给Originator角色时,它会将自己恢复至生成该Memento角色时的状态。

Memento(备忘录)

Memento角色会将Originator角色的内部信息整合在一起。在Memento角色中虽然保存了Originator角色的信息,但它不会向外部公开这些信息。

Memento角色有以下两种接口(APl)。
wide interface——宽接口(API)

Memento角色提供的“宽接口(API)”是指所有用于获取恢复对象状态信息的方法的集合。由于宽接口(API)会暴露所有Memento角色的内部信息,因此能够使用宽接口(API)的只有Originator角色。

narrowinterface——窄接口(API)

Memento角色为外部的Caretaker角色提供了“窄接口(API)”。可以通过窄接口(API)获取的Memento角色的内部信息非常有限,因此可以有效地防止信息泄露。

通过对外提供以上两种接口(API),可以有效地防止对象的封装性被破坏。

Originator角色和Memento角色之间有着非常紧密的联系。

Caretaker(负责人)

当Caretaker角色想要保存当前的Originator角色的状态时,会通知Originator角色。Originator角色在接收到通知后会生成Memento角色的实例并将其返回给Caretaker角色。由于以后可能会用Memento 实例来将Originator恢复至原来的状态,因此Caretaker角色会一直保存Memento实例。

不过,Caretaker角色只能使用Memento角色两种接口(API)中的窄接口(API),也就是说它无法访问Memento角色内部的所有信息。它只是将Originator角色生成的Memento角色当作一个黑盒子保存起来。

虽然 Originator角色和Memento角色之间是强关联关系,但Caretaker角色和Memento角色之间是弱关联关系。Memento角色对Caretaker角色隐藏了自身的内部信息。

状态模式(State)

  1. 在State模式中,我们用类来表示状态。以类来表示状态后,我们就能通过切换类来方便地改变对象的状态。

  2. 状态模式(State Pattern)主要用来解决对象在多种状态转换时,需要对外输出不同的行为的问题。状态和行为是一一对应的,状态之间可以相互转换

  3. 当一个对象的内在状态改变时,允许改变其行为,这个对象看起来像是改变了其类
    在这里插入图片描述

State(状态)

State角色表示状态,定义了根据不同状态进行不同处理的接口(API)。该接口(API)是那些处理内容依赖于状态的方法的集合。

ConcreteState(具体状态)

ConcreteState角色表示各个具体的状态,它实现了state接口。

Context(状况、前后关系、上下文)

Context角色持有表示当前状态的ConcreteState角色。此外,它还定义了供外部调用者使用State 模式的接口(API)。给代表状态的字段赋予表示当前状态的类的实例,就相当于进行了状态转移。

享元模式(Flyweight)

基本介绍

1)享元模式:当需要某个实例时,并不总是通过new关键字来生成实例,而是尽量共用已经存在的实例。即通过尽量共享实例来避免new出实例。

2)享元模式能够解决重复对象的内存浪费的问题,当系统中有大量相似对象,需要缓冲池时。不需总是创建新对象,可以从缓冲池里拿。这样可以降低系统内存,同时提高效率

3)外部状态与内部状态:

内部状态 (Intrinsic State):存储在享元对象内部并且不会随环境改变而改变的状态,内部状态可以共享

外部状态(Extrinsic State):随环境改变而改变的、不可以共享的状态。享元对象的外部状态通常由客户端保存,并在享元对象被创建之后,需要使用的时候再传入到享元对象内部。一个外部状态与另一个外部状态之间是相互独立的

4)原理:

①将具有相同内部状态的对象存储在享元池中,享元池中的对象是可以实现共享的

②需要的时候将对象从享元池中取出,即可实现对象的复用

③通过向取出的对象注入不同的外部状态,可以得到一系列相似的对象,而这些对象在内存中实际上只存储一份

④ 享元模式中外部状态相对独立,而且不会影响其内部状态,从而使得享元对象可以在不同的环境中被共享

5)常用于系统底层开发,解决系统的性能问题。像数据库连接池,里面都是创建好的连接对象,在这些连接对象中有我们需要的则直接拿来用,避免重新创建,如果没有我们需要的,则创建一个。

享元模式经典的应用场景就是池技术了,String常量池、数据库连接池、缓冲池等等都是享元模式的应用,享元模式是池技术的重要实现方式

类图

在这里插入图片描述

代码实现:

抽象享元类:
public abstract class Flyweight {
    public abstract void operation(String extrinsicState);
}

具体享元类:
public class ConcreteFlyweight extends Flyweight {
    //内部状态intrinsicState作为成员变量,同一个享元对象其内部状态是一致的
    private String intrinsicState;
    public ConcreteFlyweight(String intrinsicState) {
        this.intrinsicState = intrinsicState;
    }
	
    //外部状态extrinsicState在使用时由外部设置,不保存在享元对象中,即使是同一个对象,在每一次调用时可以传入不同的外部状态
    public void operation(String extrinsicState) {
        //实现业务方法
    }	
}

非共享具体享元类:
public class UnsharedConcreteFlyweight extends Flyweight {
    public void operation(String extrinsicState) {
        //实现业务方法
    }
}

享元工厂类:
public class FlyweightFactory {
    //定义一个HashMap用于存储享元对象,实现享元池
    private HashMap flyweights = new HashMap();

    public Flyweight getFlyweight(String key) {
       //如果对象存在,则直接从享元池获取
       if (flyweights.containsKey(key)) {
            return (Flyweight)flyweights.get(key);
        }
        //如果对象不存在,先创建一个新的对象添加到享元池中,然后返回
        else {
            Flyweight fw = new ConcreteFlyweight();
            flyweights.put(key,fw);
            return fw;
        }
    }
}

代理模式(Proxy)

代理模式:为一个对象提供一个替身,以控制对这个对象的访问,即通过代理对象访问目标对象。这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能。

代理人只代理他能解决的问题。当遇到他不能解决的问题时,还是会 “转交” 给本人去解决。另外,使用proxy可以提升处理速度,将耗时处理推迟至需要时才交给本人去处理。

远程代理: 为一个位于不同的地址空间的对象提供一个本地的代理对象,这个不同的地址空间可以在同一台主机中,也可以在另一台主机中,远程代理又称为大使。当客户端对象需要访问远程主机中的对象时可以使用远程代理。

虚拟代理: 如果需要创建一个资源消耗较大的对象,先创建一个消耗相对较小的对象来表示,真实对象只在需要时才会被真正创建。虚拟代理能够降低系统开销、缩短运行时间。

保护代理: 控制对一个对象的访问,可以给不同的用户提供不同级别的使用权限。
缓冲代理: 为某一个目标操作的结果提供临时的存储空间,以便多个客户端可以共享这些结果。

智能引用代理: 当一个对象被引用时,提供一些额外的操作,例如将对象被调用的次数记录下来等。
在这里插入图片描述
Subject(主体)

Subject角色定义了使Proxy角色和RealSubject角色之间具有一致性的接口。由于存在Subject角色,所以Client角色不必在意它所使用的究竟是Proxy角色还是RealSubject角色。

Proxy(代理人)

Proxy角色会尽量处理来自Client角色的请求。**只有当自己不能处理时,它才会将工作交给RealSubject角色。**Proxy角色只有在必要时才会生成RealSubject角色。Proxy角色实现了在Subject角色中定义的接口(API)。

RealSubject(实际的主体)

“本人” RealSubject角色会在 “代理人” Proxy角色无法胜任工作时出场。它与Proxy角色一样,也实现了在Subject角色中定义的接口(API)。

Client(请求者)

使用Proxy模式的角色。

命令模式(Command)

1)命令模式(Command Pattern):在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需在程序运行时指定具体的请求接收者即可,此时,可以使用命令模式来进行设计

2)命名模式使得请求发送者与请求接收者消除彼此之间的耦合,让对象之间的调用关系更加灵活,实现解耦。

3)在命名模式中,会将一个请求封装为一个对象,以便使用不同参数来表示不同的请求,同时命令模式也支持可撤销的操作

4)通俗易懂的理解:将军发布命令,士兵去执行。其中有几个角色:将军(命令发布者)、士兵(命令的具体执行者)、命令(连接将军和士兵)。
Invoker是调用者(将军),Receiver是被调用者(士兵),MyCommand是命令,实现了Command接口,持有接收对象
在这里插入图片描述
Command(命令)

Command角色负责定义命令的接口(API)。

Invoker(发动者)

Invoker角色是开始执行命令的角色,它会调用在Command角色中定义的接口(API)。

Receiver(接收者)

Receiver角色是Command角色执行命令时的对象,也可以称其为命令接收者。知道如何实施和执行一个请求相关的操作。

ConcreteCommand(具体的命令)

ConcreteCommand角色负责实现在Command角色中定义的接口(API)。它将一个Receiver对象和一个动作绑定调用Receiver相应的操作,实现execute。

Client(请求者)

Client角色负责生成ConcreteCommand角色并分配Receiver角色。

Invoker和Receiver之间通过Command进行解耦。

命令模式的注意事项和细节:

1)将发起请求的对象与执行请求的对象解耦。发起请求的对象是调用者,调用者只要调用命令对象的execute()方法就可以让接收者工作,而不必知道具体的接收者对象是谁、是如何实现的,命令对象会负责让接收者执行请求的动作,也就是说:”请求发起者”和“请求执行者”之间的解耦是通过命令对象实现的,命令对象起到了纽带桥梁的作用。

2)容易设计一个命令队列。只要把命令对象放到列队,就可以多线程的执行命令

3)容易实现对请求的撤销和重做

4)命令模式不足:可能导致某些系统有过多的具体命令类,增加了系统的复杂度,这点在在使用的时候要注意

5)空命令也是一种设计模式,它为我们省去了判空的操作。

6)命令模式经典的应用场景:界面的一个按钮都是一条命令、模拟CMD(DOS命令)订单的撤销/恢复、触发-反馈机制

解释器模式(Interpreter)

基本介绍:

1)在编译原理中,一个算术表达式通过词法分析器形成词法单元,而后这些词法单元再通过语法分析器构建语法分析树,最终形成一颗抽象的语法分析树。这里的词法分析器和语法分析器都可以看做是解释器

2)解释器模式(Interpreter Pattern):是指给定一个语言(表达式),定义它的文法的一种表示,并定义一个解释器,使用该解释器来解释语言中的句子(表达式)

3)应用场景

  • 应用可以将一个需要解释执行的语言中的句子表示为一个抽象语法树

  • 一些重复出现的问题可以用一种简单的语言来表达

  • 一个简单语法需要解释的场景

4)这样的例子还有,比如编译器、运算表达式计算、正则表达式、机器人等
类图:
在这里插入图片描述
AbstractExpression(抽象表达式)

AbstractExpression角色定义了语法树节点的共同接口(API),类图中是interpreter。

TerminalExpression(终结符表达式)

TerminalExpression 角色实现与文法中的终结符相关的解释操作。

NonterminalExpression(非终结符表达式)

NonterminalExpression角色为文法中的非终结符实现解释操作。

Context(文脉、上下文)

Context角色为解释器进行语法解析提供了必要的信息。

Client(请求者)

为了推导语法树,Client角色会调用TerminalExpression角色和NonterminalExpresion角色。

解释器模式的注意事项和细节:

1)解释器模式要慎用,难度比较大

2)当有一个语言需要解释执行,可将该语言中的句子表示为一个抽象语法树,就可以考虑使用解释器模式,让程序具有良好的扩展性

3)使用解释器可能带来的问题:解释器模式会引起类膨胀、解释器模式采用递归调用方法,将会导致调试非常复杂、效率可能降低

图解 23 种设计模式 就一个类而言,应该仅有一个引起它变化的原因。如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会削弱或者抑制这个类完成其他职责的能力。这种耦合会导致脆弱他的设计,当变化发生时,设计会遭受到意想不到的破坏;软件设计真正要做的许多内容就是发现职责并把那些职责相互分离。软件实体应该可以扩展,但不可修改。该原则是面向对象设计的核心所在,遵循这个原则可以带来面向对象技术所声称的可维护、可扩展、可复用、灵活性好。设计人员必须对于他设计的模块应该对哪种变化封闭做出选择,必须先猜测出最有可能发生的变化 阅读详情

相关推荐

SpringAi 通过大模型来实现调用自己的Api

摘要 本文介绍了如何利用Spring AI的Tools机制扩展大模型能力,实现业务系统集成。通过@Tool和@ToolParam注解定义工具方法,将订单查询和关闭功能暴露给大模型调用。关键实现包括:1)使用详细描述标注工具方法和参数;2)在ChatClient中注册工具服务;3)集成对话记忆保持上下文。该方法使AI具备操作业务系统的能力,形成"认知-决策-执行"闭环,大幅提升了模型在实际业务场景中的应用价值。

又要搬砖了 835

图解23种设计模式

图解23种设计模式创建型模式:1、单例模式2、工厂模式结构型模式:行为型模式: 创建型模式: 1、单例模式 单例(Singleton)模式的定义:指一个类只有一个实例,且该类能自行创建这个实例的一种模式。例如,Windows 中只能打开一个任务管理器,这样可以避免因打开多个任务管理器窗口而造成内存资源的浪费,或出现各个窗口显示内容的不一致等错误。 单例模式有 3 个特点: 1、’单例类只有一个实例对象; 2、该单例对象必须由单例类自行创建; 3、单例类对外提供一个访问该单例的全局访问点。 单例模式的结构与实

weixin_45429720的博客 3483

ArcMap新手必看:5分钟搞定面要素的四至信息提取(附字段重命名技巧)

本文为ArcMap新手提供了快速提取面要素四至信息的详细教程,包括数据准备、坐标系选择、批量处理技巧及字段重命名优化方案。通过实战步骤和Python脚本示例,帮助用户高效完成GIS数据处理任务,特别适合行政区划数据分析和报告生成。

weixin_29266007的博客 384

图解设计模式 (结城浩 著)

第1部分 适应设计模式   第1章Iterator(迭代器) 模式-一个一个遍历(已看)   第2章Adapter(适配器) 模式-加个"适配器"模式以便于复用(已看) 第2部分 交给子类   第3章Template Method(模板方法) 模式-将具体处理交给子类(已看)   第4章Factory Method(工厂方法) 模式-将实例的生成交给子类(已看) 第3部...

weixin_34224941的博客 827

从零到一:3D Slicer与MONAI在医学影像中的AI革命

本文探讨了3D Slicer与MONAI在医学影像分析中的革命性应用,展示了如何通过开源工具实现高效的三维影像处理和AI增强分析。结合临床案例,详细介绍了从数据准备到AI分析的全流程,显著提升诊断效率和精度,推动医学影像技术迈向新纪元。

tcp8optimizer的博客 339

基于 parallels ubuntu 20.04 LTS (focal) 的ros+px4+gazebo 安装

基于 parallels ubuntu 20.04 LTS (focal) 的ros+px4+gazebo 安装。

weixin_40132006的博客 2239

图解设计模式,看完秒懂!!!

点击关注公众号,实用技术文章及时了解在本公号连载的《设计模式是什么鬼》终于出书了,由人民邮电出版社出版,书名:秒懂设计模式,作者:刘韬,笔名:凸凹。以下节选自本书第一章“初探”,这里免费提...

Java知音 2196

ABAQUS应用15——Abaqus软件中边界条件与力学中自由度的关系

核心关系:Abaqus通过约束自由度实现边界条件,自由度类型由单元决定。正确设置步骤:确定模型类型(实体/梁/壳)。识别节点的自由度(平动或转动)。根据实际约束施加对应的自由度限制。验证:通过检查变形模式、反力分布等确认边界条件合理性。正确理解自由度与边界条件的关系,是确保有限元模型准确模拟实际物理行为的关键。

George的博客 1540

图解设计模式

图解设计模式

weixin_42248522的博客 130

大华事件检测智能服务器,大华股份:高速公路智能事件检测 解决方案

1方案背景随着我国基础设施建设的飞速发展,公路尤其是高速公路的总里程数年年攀升。交通运输部统计数据显示,截止2017年底全国公路总里程477.35万公里,其中高速公路13.65万公里,位居世界第一。高速公路的运营和管理作为全国交通管理的重要组成部分日益受到严峻挑战,交通拥堵和事故频发已成为高速公路上非常突出的问题。抛洒物、行人、车辆不规则行驶等事件是导致以上结果的重要原因。基于视频分析的高速公路智...

weixin_39523887的博客 1822

抖音中动态生成msToken的方法

抖音中动态生成msToken的方法

sh_moranliunian的博客 2483

MVC图解

 最近一直在看书,也不想写东西。贴张图了!

可乐_Blog 1891

CryoEM - 冷冻电镜 基于深度学习的 从头重构(Ab-initio Reconstruction) 开源项目 教程

冷冻电镜(CryoEM) 是一种成像方式,为蛋白质和其他生命基本组成部分的动态,提供独特的观察方式。从数百万噪声和随机取向的二维投影中,以计算效率高的方式,联合估计生物大分子的姿态、三维结构和构象异质性。

AGI 1554

【学习笔记】软件设计模式(一)基本概念与归纳总结

软件设计模式之基本概念文章目录软件设计模式概述模式的分类面向对象设计原则UML图类的UML图示类之间的关系 软件设计模式概述 设计模式一般包含模式名称、问题、目的、解决方案、效果、实例代码和相关设计模式等基本要素,4个关键要素为:模式名称、问题、解决方案、效果。 模式的分类 根据目的可分为三类: 创建型模式。主要用于创建对象。 结构型模式。主要用于处理类或对象的组合。 行为型模式。主要用于描述...

阿J的博客 1218

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

软件设计师备考笔记【day2】-UML 图解 | 面向对象 | 设计模式

目录一,uml建模1,基础概念2, UML 核心图分类3,关系二,面向对象1,三大核心特性2,设计原则三,设计模式1,模式分类总览2,创建型模式3,结构型模式4,行为型模式5,根据类图识别设计模式 1,基础概念(1)uml包括(2)构造块包括(3)事务包括2, UML 核心图分类3,关系参与者之间的关系:泛化关系参与者和用例之间:关联关系用例之间:包含,扩展,泛化1,三大核心特性封装,继承,多肽2,设计原则所有设计原则最终目标:提高内聚、降低耦合,符合开闭原则1,模式分类总览2,创建型模式3,结构型模式4

2301_76506734的博客 635

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

MVC与MVVM图解

cangqiong_xiamen的博客 195

图解Java设计模式之命令模式

图解Java设计模式之命令模式智能生活项目需求命令模式基本介绍命令模式的原理类图 智能生活项目需求 看一个具体的需求 我们买类一套智能家电,有照明灯、风扇、冰箱、洗衣机,我们只要在手机上安装app就可以控制对这些家电工作。 这些智能家电来自不同的厂家,我们不想针对每一种家电都安装一个App,分别控制,我们希望只要一个App就可以控制全部智能家电。 要实现一个app控制所有智能家电的需要,则每个...

不一样的花朵的博客 514

【笔记整理】图解设计模式 | 导航

【笔记整理】图解设计模式 | 关于UML 第1部分 适应设计模式 【笔记整理】图解设计模式 | 第1章 Iterator模式(一个一个遍历) 【笔记整理】图解设计模式 | 第2章 Adapter模式(加个“适配器”以便于复用) 第2部分 交给子类 【笔记整理】图解设计模式 | 第3章 Template Method模式(将具体处理交给子类) 【笔记整理】图解设计模式 | 第...

520

【十二】图解mybatis日志模块之设计模式

阅读优秀开源项目开源真切体会到软件优秀的设计思想,当哪天你能看懂代码设计的好坏,并且在自己实际工作中对设计多一些思考,那么你将不再会有焦虑,因为你的能力名副其实。

作者:大头兵(kit) 1229

设计模式:职责链模式

职责链模式 1.OA系统采购审批需求 学校OA系统的采购审批项目:需求是 采购员采购教学器材 如果金额 小于等于5000, 由教学主任审批 (0<=x<=5000) 如果金额 小于等于10000, 由院长审批 (5000<x<=10000) 如果金额 小于等于30000, 由副校长审批 (10000<x<=30000) 如果金额 超过30000以上,有校长审批 ( 30000<x) 请设计程序完成采购审批项目 1.1 传统方案解决OA系统审批 传统方案解决OA系

weixin_43967582的博客 238

轻松掌握23种常见设计模式(看完直接猛猛做题)持续更新

这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。定义一个用于创建对象的接口,让子类决定实例化哪个产品类对象。工厂方法使一个产品类的实例化延迟到其工厂的子类。是一种为访问类提供一个创建一组相关或相互依赖对象的接口且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品。

weixin_62182040的博客 3015

命令模式

一、命令模式介绍 在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个。我们只需要在程序运行时指定具体的请求接收者即可,此时可以使用命令模式来设计。 命令模式使得请求发送者与请求接收者消除彼此之间的耦合,让对象之间的调用关系更加灵活,实现解耦。在命令模式中,会将一个请求封装为一个对象,以便使用不同参数来表示不同的请求...

学习记录 406

【白话设计模式】23种设计模式一句话通俗讲解,女朋友都能听懂(导航篇)

设计模式专栏,导航篇

公号:一条coding 1万+

2017书单

2017书单 ===== 《极简欧洲史》 约翰·赫斯特   20170309

谭哥杂谈 485

深入浅出设计模式【导语、内含23种设计模式和踩坑经验】

设计模式是软件工程中解决常见问题的可复用方案模板,能帮助开发者编写清晰、灵活、可维护的代码。本文将通过系列文章深入解析经典设计模式,包括单例、工厂方法、抽象工厂等,涵盖核心概念、适用场景、类图分析、实现方式及最佳实践。结合Java语言、开源框架和业务案例,旨在为开发者提供理论与实战结合的深度指南,提升系统设计能力。适合希望夯实基础或优化设计的中高级开发者参考。

NeoLshu的博客 967
上一篇: 侯捷c++11课程学习笔记
下一篇: 数字信号处理(一)绪论
枫2333
博客等级 码龄7年 69粉丝 22原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值