9

Golang 中的外观facade设计模式

 1 year ago
source link: https://www.jdon.com/67190.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Golang 中的外观facade设计模式

与构建的物理世界一样,软件架构也受模式控制。这些模式充当蓝图,塑造软件系统的结构和行为。这些关键模式之一是外观facade设计模式,虽然常常不为人所知,但不可否认的重要。

外观facade模式源于四人帮 1994 年出版的颇具影响力的著作《设计模式:可重用面向对象软件的元素》,它不仅仅是一个花哨的架构术语。它体现了一个简单而强大的概念。

外观facade,就像它在建筑中的同名一样,为更复杂的子系统提供了一个简单、统一的接口。它隐藏了复杂性,将简单、结构和优雅带到了前面。

为什么外观模式很重要?
这一切都可以归结为古老的软件开发原则:保持简单、愚蠢(KISS)和不要重复(DRY)。外观隐藏了系统的复杂性,并为客户端提供了简化的界面。它通常涉及一个包含客户端需要的成员集的单个包装类。这些成员代表外观客户端访问系统并隐藏实现细节。

通过结合外观模式,开发人员可以确保他们的代码保持干净、精简,更重要的是,可维护。这种模式实现了松散耦合并提高了代码的可重用性。让我们通过用 Go 编程语言编写的具体示例来考虑这一点。

揭开表面的面纱:5 个现实例子

1. 数据库连接
想象一个场景,我们需要连接到数据库,运行查询,然后断开连接。如果没有外观,我们需要记住操作的顺序,创建连接对象,编写查询,执行查询,获取结果,然后关闭连接。

// 没有 Facade

type Database struct { 
DatabaseConnection *sql.DB 
} 

func  (db *Database) Connect() { 
 // 连接代码
} 

func  (db *Database) Query() { 
 // 查询代码
} 

func  (db * Database) Disconnect() { 
 // 断开连接的代码// 用法
var db Database 
db.Connect() 
db.Query() 
db.Disconnect()

但是,我们可以将此序列简化为带有 Facade 的单个调用。

// 对于 Facade

type DatabaseFacade struct { 
Database *Database 
} 

func  (dbf *DatabaseFacade) ExecuteQuery() { 
dbf.Database.Connect() 
dbf.Database.Query() 
dbf.Database.Disconnect() 
} 

// 用法
var dbf DatabaseFacade 
dbf.ExecuteQuery()

2. 文件系统操作
假设我们必须读取一个文件,处理文本,然后写入另一个文件。如果没有外观,这将涉及几个不同的操作。但是,我们可以使用 Facade 将此序列封装为单个操作。

// 无外观

type FileOperations struct { 
 // ...
 } 

func  (fo *FileOperations) OpenFile() { 
 // ...
 } 

func  (fo *FileOperations) ReadFile() { 
 // ...
 } 

func  (fo * FileOperations) ProcessText() { 
 // ...
 } 

func  (fo *FileOperations) WriteToFile() { 
 // ...
 } 

func  (fo *FileOperations) CloseFile() { 
 // ...
 } 

// 用法
var fo FileOperations 
fo.OpenFile() 
fo.ReadFile() 
fo.ProcessText()
fo.WriteToFile() 
fo.CloseFile() 

// 采用 Facade

type FileOperationsFacade struct { 
FileOperations *FileOperations 
} 

func  (fof *FileOperationsFacade) ProcessFile() { 
fof.FileOperations.OpenFile() 
fof.FileOperations.ReadFile() 
fof.FileOperations. ProcessText() 
fof.FileOperations.WriteToFile() 
fof.FileOperations.CloseFile() 
} 

// 用法
var fof FileOperationsFacade 
fof.ProcessFile()

3. API 包装器
假设您使用具有复杂设置或查询结构的外部 API。您可以将其封装在 Facade 中,而不是将这种复杂性分散到整个代码中。

// 没有 Facade

type ComplexAPI struct { 
 // ...
 } 

func  (api *ComplexAPI) Setup() { 
 // ...
 } 

func  (api *ComplexAPI) Authenticate() { 
 // ...
 } 

func  (api * ComplexAPI) Query() { 
 // ...
 } 

func  (api *ComplexAPI) cleanup() { 
 // ...
 } 

// 用法
var api ComplexAPI 
api.Setup() 
api.Authenticate() 
api.Query() 
api .Cleanup() 

// 使用 Facade

type APIFacade struct {
ComplexAPI *ComplexAPI 
} 

func  (of *APIFacade) UseAPI() { 
af.ComplexAPI.Setup() 
af.ComplexAPI.Authenticate() 
af.ComplexAPI.Query() 
af.ComplexAPI.Cleanup() 
} 

// APIFacade af的用法
var af APIFacade
af.UseAPI()

4. Web服务器初始化
让我们考虑使用各种中间件、路由和配置来初始化 Web 服务器。使用 Facade 可以简化此过程。

// 没有 Facade

type Server struct { 
 // ...
 } 

func (s *Server) Initialize () { 
 // ...
 } 

func (s *Server) AddMiddleware () { 
 // ...
 } 

func (s * Server) DefineRoutes () { 
 // ...
 } 

func (s *Server) Start () { 
 // ...
 } 
// 用法
var s Server 
s .Initialize () 
s .AddMiddleware () 
s .DefineRoutes () 
s .Start () 

// 有 Facade

type ServerFacade struct {
Server *Server 
} 

func (sf *ServerFacade) StartServer () { 
sf .Server .Initialize () 
sf .Server .AddMiddleware () 
sf .Server .DefineRoutes () 
sf .Server .Start () 
} 

// 用法
var sf ServerFacade 
sf .StartServer ()

5. 电子商务订单处理
考虑一个电子商务应用程序,其中订单要经历多个步骤,例如验证、付款处理、库存更新和运输。如果没有外观,每个步骤都需要单独调用。

// 没有 Facade

type OrderSystem struct { 
 // ...
 } 

func  (os *OrderSystem) ValidateOrder() { 
 // ...
 } 

func  (os *OrderSystem) ProcessPayment() { 
 // ...
 } 

func  (os * OrderSystem) UpdateInventory() { 
 // ...
 } 

func  (os *OrderSystem) ShipOrder() { 
 // ...
 } 

// 用法
var os OrderSystem 
os.ValidateOrder() 
os.ProcessPayment() 
os.UpdateInventory() 
os .ShipOrder()

然而,Facade 可以将此过程简化为单个操作,从而提高可读性和易用性。

// 使用 Facade

type OrderSystemFacade struct { 
OrderSystem *OrderSystem 
} 

func  (osf *OrderSystemFacade) PlaceOrder() { 
osf.OrderSystem.ValidateOrder() 
osf.OrderSystem.ProcessPayment() 
osf.OrderSystem.UpdateInventory() 
osf.OrderSystem.ShipOrder() 
} 

// 用法
var osf OrderSystemFacade 
osf.PlaceOrder()

此示例说明了外观模式如何显着简化与复杂系统的交互,使代码更易于理解和维护。

结束语
尽管外观模式很强大,但它也有潜在的缺点。最突出的是创建“上帝对象”的风险——一个知道太多或做太多事情的类。这可能使外观本身成为一个复杂的野兽,违背了它所服务的目的。为了缓解这种情况,开发人员必须确保明智且负责任地使用外观。

此外,外观有时会变得非常方便,以至于开发人员可能会过度使用它们,从而创建不必要的层。这可能会导致性能开销和额外的复杂性。

总之,外观模式是一种基本的设计模式,它提供了许多好处,例如简单性、结构和代码可重用性。但是,与任何工具或模式一样,必须明智地使用它。关键在于了解其优点和缺点,并在有意义的地方应用它,同时考虑简单性和代码可维护性的原则。毕竟,我们的目标是让我们作为开发人员的生活变得更轻松,而不是更困难!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK