go

golang外观模式

介绍

外观模式(Facade Pattern)是一种结构型设计模式,它提供了一个简化的接口,用于访问复杂子系统的一组接口。它隐藏了子系统的复杂性,使得客户端可以通过一个简单的接口与子系统进行交互,而不需要了解子系统的内部实现细节。

在外观模式中,有一个外观(Facade)对象,它代表了客户端与子系统之间的统一接口。外观对象知道如何调用子系统的各种方法,将客户端的请求委派给适当的子系统对象进行处理。客户端只需要与外观对象进行交互,而不需要直接与子系统对象进行通信。

外观模式的主要目的是简化客户端的使用,通过提供一个高层次的接口,屏蔽了子系统的复杂性,同时还可以降低客户端与子系统之间的耦合度。

涉及到的角色有:

  • 外观(Facade):外观对象是客户端与子系统之间的接口,它知道如何将客户端的请求转发给适当的子系统对象。外观对象通常封装了一系列的方法,用于处理客户端的请求,并将其委派给子系统对象进行实际处理。
  • 子系统(Subsystem):子系统是一组相关的类或对象,实现了子系统的功能。子系统对象可以单独使用,但通常是通过外观对象来与客户端进行交互。
  • 客户端(Client):客户端是使用外观模式的对象。它通过外观对象来与子系统进行交互,而不需要直接与子系统对象进行通信。

file

优点

  • 简化接口:外观模式提供了一个简化的接口,隐藏了子系统的复杂性,使得客户端更容易使用子系统。
  • 降低耦合度:外观模式将客户端与子系统之间的依赖关系解耦,使得它们可以独立演化,互不影响。
  • 提高灵活性:外观模式使得子系统的内部变化不会影响到客户端,只需要调整外观对象即可。

缺点

  • 违反开闭原则:在外观模式下,如果需要新增或修改子系统的功能,可能需要修改外观类。这违反了开闭原则,因为对外观类的修改可能会影响到客户端代码。
  • 增加了系统的复杂性:虽然外观模式可以简化客户端的使用,但它也引入了一个额外的抽象层。这可能会增加系统的复杂性,特别是在处理复杂的子系统时,外观类可能需要涉及大量的逻辑和方法。
  • 过度使用导致滥用:如果在设计中过度使用外观模式,将所有的子系统功能都封装在外观类中,可能导致外观类变得臃肿,违反了单一职责原则。此外,过度使用外观模式可能会使系统更难理解和维护。
  • 降低了灵活性和可定制性:外观模式隐藏了子系统的复杂性,但也意味着客户端无法直接访问子系统的所有功能。如果需要对子系统进行更详细的定制和控制,可能需要绕过外观对象并直接与子系统进行交互。
  • 可能引入不必要的依赖关系:客户端与外观对象之间建立了依赖关系,如果客户端需要与多个不同的外观对象进行交互,可能导致客户端与外观对象之间的耦合度增加。

使用场景

  • 图形用户界面(GUI)库:在图形用户界面库中,可以使用外观模式来提供一个简化的接口,以便客户端可以简单地创建和操作用户界面元素,而不需要了解底层的复杂细节,如窗口管理、图形绘制、事件处理等。
  • 支付系统:在一个支付系统中,可能涉及到多个支付渠道(如信用卡、支付宝、微信支付等),每个渠道都有自己的接口和处理逻辑。使用外观模式,可以将这些支付渠道的接口封装在一个外观类中,为客户端提供一个统一的支付接口,客户端只需要与外观对象进行交互,而不需要直接与各个支付渠道进行交互。
  • 多媒体播放器:在一个多媒体播放器中,可能需要处理音频、视频、字幕等多个组件,每个组件都有自己的接口和处理逻辑。使用外观模式,可以将这些组件的接口封装在一个外观类中,为客户端提供一个简化的播放控制接口,客户端只需要与外观对象进行交互,而不需要直接与各个组件进行交互。
  • 电子商务系统:在一个电子商务系统中,可能涉及到多个子系统,如用户管理、库存管理、订单管理等。使用外观模式,可以将这些子系统的接口封装在一个外观类中,为客户端提供一个简化的接口,客户端只需要与外观对象进行交互,而不需要直接与各个子系统进行交互。
  • 操作系统API:操作系统提供了丰富的API用于处理文件系统、网络通信、进程管理等。使用外观模式,可以将这些底层的系统调用封装在一个外观类中,为应用程序提供一个简化的接口,应用程序只需要与外观对象进行交互,而不需要直接与底层的系统调用进行交互。

代码示例

package main

import "fmt"

type Sport interface {
    Play()
}

type Football struct{}

type Basketball struct{}

func PlayFootball() *Football {
    return &Football{}
}

func PlayBasketball() *Basketball {
    return &Basketball{}
}

func (f *Football) Play() {
    fmt.Println("Play football")
}

func (b *Basketball) Play() {
    fmt.Println("Play basketball")
}

type SportFacade struct {
    football   *Football
    basketball *Basketball
}

func PlaySportFacade() *SportFacade {
    return &SportFacade{
        football:   PlayFootball(),
        basketball: PlayBasketball(),
    }
}

//func (f *SportFacade) PlayFootball() {
//  f.football.Play()
//}
//func (f *SportFacade) PlayBasketball() {
//  f.basketball.Play()
//}

func (f *SportFacade) Playing() {
    f.football.Play()
    f.basketball.Play()
}
func main() {
    sport := PlaySportFacade()
    //sport.PlayFootball()
    //sport.PlayBasketball()
    sport.Playing()
}

客户端创建了外观对象SportFacade,并调用了Playing()方法,只需要与外观对象进行交互,而不需要直接与子系统进行交互。

分类: go
0 0 投票数
文章评分
订阅评论
提醒
guest

0 评论
最旧
最新 最多投票
内联反馈
查看所有评论

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部
0
希望看到您的想法,请您发表评论x