首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

23种设计模式之二

观察者模式

以下是使用Golang实现观察者模式的示例代码:

ervers }

func main() {// 创建主题对象和观察者对象,并执行操作subject := &ConcreteSubject{}observer1 := &ConcreteObserver1{}observer2 := &ConcreteObserver2{}subject.Attach(observer1)subject.Attach(observer2)subject.Notify()}

在上面的示例中,我们首先定义了一个 `Observer` 接口,它包含一个 `Update` 方法。然后,我们定义了两个具体的观察者类 `ConcreteObserver1` 和 `ConcreteObserver2`,它们实现了 `Update` 方法以更新数据。接着,我们定义了一个 `Subject` 接口,它包含三个方法:`Attach` 用于将观察者添加到主题对象中,`Detach` 用于从主题对象中删除观察者,以及 `Notify` 用于通知所有观察者进行更新操作。在 `ConcreteSubject` 类中,我们实现了 `Subject` 接口,并维护了一个观察者列表。在 `Attach` 方法中,我们将传入的观察者添加到列表中。在 `Detach` 方法中,我们查找列表中与传入观察者相等的元素,并将其从列表中移除。在 `Notify` 方法中,我们遍历观察者列表,并调用每个观察者的 `Update` 方法来更新数据。在 `main` 函数中,我们首先创建一个主题对象和两个观察者对象,并将这些观察者添加到主题对象中。然后,我们调用主题对象的 `Notify` 方法来通知所有观察者进行更新操作。迭代器模式(Iterator Pattern)

以下是使用Golang实现迭代器模式的示例代码:

}

在上面的示例中,我们首先定义了一个 接口,它包含两个方法: 用于检查是否还有下一个元素,以及 用于获取下一个元素。然后,我们定义了一个具体的迭代器类 ,它实现了 和 方法以遍历数据。

接着,我们定义了一个 接口,它包含一个 方法,该方法返回一个迭代器对象。然后,我们定义了一个具体的可迭代对象类 ,它实现了 方法以返回一个迭代器对象。

在 函数中,我们首先创建一个可迭代对象,并通过调用 方法创建一个迭代器对象。然后,我们使用迭代器对象来遍历数据,并打印每个元素。

中介者模式

以下是使用Golang实现状态模式的示例代码:

在上面的示例中,我们首先定义了一个 接口,它包含一个 方法。然后,我们定义了一个 接口,它包含两个方法: 用于设置中介者对象,以及 用于接收消息。

接着,我们定义了一个具体的中介者类 ,它实现了 方法以转发消息给不同的同事对象。

在 类中,我们检查传入的同事对象类型,并将消息转发给另一个同事对象。

在 类中,我们实现了 和 方法以设置中介者对象和接收消息。此外,我们还定义了一个 方法,该方法向中介者对象发送消息以转发给另一个同事对象。

在 类中,我们同样实现了 、 和 方法,并且通过 方法将同事 A 对象设置为自己的同事对象。

在 函数中,我们首先创建一个中介者对象和两个同事对象,并将它们按照需要连接起来。然后,我们分别调用两个同事对象的 方法向中介者对象发送消息。由于中介者对象维护了所有同事对象的引用,因此它可以将消息转发给目标同事对象。

访问者模式(Visitor Pattern)

以下是使用Golang实现访问者模式的示例代码:

在上面的示例中,我们首先定义了一个 接口,它包含两个方法: 和 ,用于访问具体元素类 和 。

接着,我们定义了一个 接口,它包含一个 方法,用于接收访问者对象并调用相应的访问者方法。

然后,我们实现了具体的元素类 和 ,它们分别实现了 接口,并提供了自己的操作方法 和 。在 方法中,我们将调用传递进来的访问者对象的相应方法。

最后,我们实现了具体的访问者类 ,它实现了 接口,并提供了用于访问不同元素的具体方法。在这些方法中,我们打印一条信息,表明当前正在访问哪个元素,并调用该元素的操作方法。

在 函数中,我们首先创建了一个 对象和一个 对象,并将它们分别传递给 对象的 和 方法。由于每个元素都实现了 接口,它们可以接收任何访问者对象。因此,在这里我们使用了同一个 对象来访问它们。在访问过程中,我们可以看到输出了每个元素对应的操作方法。

解释器模式(Interpreter Pattern)

以下是使用Golang实现解释器模式的示例代码:

在上面的示例中,我们首先定义了一个 接口,它包含一个 方法,用于解析表达式并返回结果。

接着,我们实现了具体的表达式类 、 和,它们分别表示数字、加法和减法。在 方法中,我们根据具体的语法规则计算并返回结果。

然后,我们实现了解释器环境类 ,它提供了一个 方法,用于接收表达式字符串并进行解析和计算。在该方法中,我们首先将表达式字符串分割成单独的字符,然后根据语法规则逐一计算每个部分,并使用一个栈来保存中间结果。在遇到数字时,我们创建一个 对象并将其压入栈中。在遇到加号或减号时,我们弹出栈顶的两个元素并创建一个对应的 或 对象,然后将其压入栈中。最终,当整个表达式被解析完毕后,栈中只剩下一个元素,就是最终的计算结果。

在 函数中,我们首先创建了一个 对象,并将表达式字符串传递给它的 方法进行解析和计算。如果出现错误,则输出相应的提示信息。否则,输出计算结果。

总的来说,在解释器模式中,我们通过定义一个解释器环境类来封装表达式解析和计算的细节,并使用具体的表达式类来实现不同的语法规则。这样,我们就可以将表达式和解释器分离开来,使得它们可以相互独立地变化和扩展。

##策略模式

以下是使用Golang实现策略模式的示例代码:

在上面的示例中,我们首先定义了一个 接口,它包含一个 方法,用于实现具体的排序算法。

接着,我们实现了两个具体的算法类: 和 ,它们分别实现了 接口,并提供了自己的排序算法。在这些算法中,我们使用冒泡排序和快速排序来对数据进行排序。

然后,我们实现了一个上下文类 ,它包含一个 成员变量,用于保存当前使用的排序算法。在 方法中,我们将传递进来的排序算法设置为当前算法。在 方法中,我们调用当前算法的 方法来对数据进行排序。

在 函数中,我们首先创建了一个 对象,并使用冒泡排序算法对一个数据集进行排序。然后,我们再使用快速排序算法对另一个数据集进行排序,并观察输出结果。

总的来说,在策略模式中,我们通过定义一个上下文类来封装具体的算法实现,并将不同的算法实现封装在不同的策略类中。这样,我们就可以在运行时动态切换算法,使得代码更加灵活和可扩展。

##命令模式

以下是使用Golang实现命令模式的示例代码:

) Action()

type ConcreteReceiverB struct {}

func (crb *ConcreteReceiverB) Action()

// 实现具体的命令类type ConcreteCommandA struct

func (cca *ConcreteCommandA) Execute()

type ConcreteCommandB struct

func (ccb *ConcreteCommandB) Execute()

// 实现调用者类type Invoker struct

func (i *Invoker) SetCommand(command Command)

func (i *Invoker) ExecuteCommand() }

func main() {// 创建接收者对象并设置命令receiverA := &ConcreteReceiverA{}commandA := &ConcreteCommandAinvoker := &Invoker{}invoker.SetCommand(commandA)

}

在上面的示例中,我们首先定义了一个 `Receiver` 接口和一个 `Command` 接口,它们分别包含一个方法:`Action` 和 `Execute`。

接着,我们实现了两个具体的接收者类:`ConcreteReceiverA` 和 `ConcreteReceiverB`,它们都实现了 `Receiver` 接口,并提供了自己的行为。

然后,我们实现了两个具体的命令类:`ConcreteCommandA` 和 `ConcreteCommandB`,它们分别实现了 `Command` 接口,并将一个接收者对象保存在成员变量中。在 `Execute` 方法中,我们调用接收者对象的 `Action` 方法来执行具体的行为。

接着,我们实现了一个调用者类 `Invoker`,它包含一个命令对象,并提供了设置和执行命令的方法。在 `ExecuteCommand` 方法中,我们调用当前命令对象的 `Execute` 方法来执行具体的操作。

在 `main` 函数中,我们首先创建了一个接收者对象和一个命令对象,并将命令对象设置到调用者对象中。然后,我们执行命令并观察输出结果。接着,我们再创建另一个接收者对象和命令对象,并将其设置到调用者对象中,再次执行命令并观察输出结果。

总的来说,在命令模式中,我们通过将请求封装在命令对象中,使得请求的发送者和接收者之间解耦。这样,我们就可以实现对请求的撤销、重做等操作,以及将多个请求组合成一个复合命令。

##备忘录模式(Memento Pattern)

以下是使用Golang实现备忘录模式的示例代码:

在上面的示例中,我们首先定义了一个 类,它包含一个 成员变量和两个方法: 用于获取状态值,以及 用于设置状态值。

接着,我们实现了一个发起者类 ,它包含一个 成员变量和三个方法: 用于设置状态值, 用于获取状态值,以及 用于保存备忘录。在 方法中,我们创建一个新的备忘录对象并将当前状态值保存到其中。

然后,我们实现了一个管理者类 ,它包含一个 数组用于保存备忘录对象,以及两个方法: 用于添加备忘录对象,以及 用于获取指定索引位置的备忘录对象。

在 函数中,我们首先创建了一个发起者对象和一个管理者对象。然后,我们设置初始状态并保存备忘录,再修改状态并再次保存备忘录。接着,我们分别恢复两个备忘录,并观察输出结果。

总的来说,在备忘录模式中,我们可以通过保存对象的状态信息到备忘录对象中,并将备忘录对象保存到管理者对象中。这样,我们就可以在需要的时候从管理者对象中获取相应的备忘录对象,并将其恢复到原始对象的状态。这种方式使得我们可以实现撤销、重做等操作,同时保护了对象的封装性和一致性。

##责任链模式

在上面的示例中,我们首先定义了一个 接口,它包含两个方法: 用于设置下一个处理器对象,以及 用于处理请求。

接着,我们实现了两个具体的处理器类: 和 。在实现过程中,我们首先判断当前请求是否符合自身能够处理的范围,如果是则进行处理;否则将请求转发给下一个处理器对象。如果没有下一个处理器对象,则输出一个提示信息。

然后,我们实现客户端代码,在其中创建处理器对象并设置处理链。然后,我们连续发送三次请求,并观察输出结果。

总的来说,在责任链模式中,我们将多个处理器对象组成一条链,并依次对请求进行处理。这样,我们就可以在运行时动态地组合和切换处理器对象,从而实现灵活的请求处理方式。同时,责任链模式还可以避免请求发送者和接收者之间的直接耦合,增加系统的灵活性和可扩展性。

##状态模式

在上面的示例中,我们首先定义了一个 接口,它包含一个方法:,用于处理请求并根据需要更新状态。

接着,我们实现了两个具体的状态类: 和 。在实现过程中,我们使用 输出语句模拟具体的行为,并在每次处理完成后将状态更新为下一个状态。

然后,我们实现了一个上下文类 ,它包含一个状态成员变量和两个方法: 用于设置状态值,以及 用于发送请求。

在 函数中,我们首先创建了一个上下文对象,并将其初始状态设置为 。然后,我们连续发送三次请求,并观察输出结果。

总的来说,在状态模式中,我们将对象的行为根据不同状态进行封装,并定义一个上下文类来管理状态的转换和请求的发送。这样,我们可以在运行时动态切换状态,同时保证了对象的封装性和一致性。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20230623A002UL00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券