第3节 开闭原则


❤️💕💕Java和Golang的设计模式,设计模式介绍、创建者模式、结构型模式、行为型模式。Myblog:http://nsddd.topopen in new window


[TOC]

原则

警告

开闭原则 (Open-Closed Principle, OCP)

类的改动是通过增加代码进行的,而不是修改源代码。

没有使用开闭原则

💡简单的一个案例如下:

// The principle of opening and closing
// Path: 79-main.go
package main

import (
	"fmt"
)

// The principle of opening and closing
type Banker struct {
}

// Deposit business
func (b *Banker) Deposit() {
	fmt.Println("存款成功")
}

// Withdrawal business
func (b *Banker) Withdraw() {
	fmt.Println("取款成功")
}

// Transfer business
func (b *Banker) Transfer() {
	fmt.Println("转账成功")
}

func main() {
	b := &Banker{}

	b.Deposit()
	b.Withdraw()
	b.Transfer()

}

需求:我们需要加一个股票功能,我们需要额外添加功能。

注意

但是我们类可能看不出来,如果一个类很庞大,添加功能的时候就需要特别小心。

这就是设计的弊端。

那么,如果我们拥有接口, interface这个东西,那么我们就可以抽象一层出来,制作一个抽象的Banker模块,然后提供一个抽象的方法。 分别根据这个抽象模块,去实现支付Banker(实现支付方法),转账Banker(实现转账方法)

image-20221127231259024

提示

那么即使 Banker 的添加,不会修改 任何已经稳定的代码,出现问题也不会连累其他模块。

// 开闭原则
package main

import "fmt"

// 抽象的银行接口
type Banker interface {
	Deposit()  //存款
	Withdraw() //取款
	Transfer() //转账
}

// 实现银行接口
type Bank struct {
}

// 存款
func (b *Bank) Deposit() {
	fmt.Println("存款成功")
}

// 取款
func (b *Bank) Withdraw() {
	fmt.Println("取款成功")
}

// 转账
func (b *Bank) Transfer() {
	fmt.Println("转账成功")
}

// 我们可以再定义一个支付宝的银行接口
type Alipay struct {
}

// 存款
func (a *Alipay) Deposit() {
	fmt.Println("支付宝存款成功")
}

// 取款
func (a *Alipay) Withdraw() {
	fmt.Println("支付宝取款成功")
}

func main() {
	b := &Bank{}  //实现了接口
	b.Deposit()
	b.Withdraw()
	b.Transfer() 

	a := &Alipay{}
	a.Deposit()
	a.Withdraw()
}

注意

Alipay{} 结构体并不是需要去实现接口。所以作为扩展性。

实现架构层,基于抽象层业务封装

提示

实现一个架构层,基于抽象层进行业务封装,针对 interface 进行封装。

// The principle of opening and closing
package main

import "fmt"

//Abstract bank interface
type Banker interface {
	Deposit()  //deposit
	Withdraw() //Withdrawal
	Transfer() //Transfer
}

//Implement the bank interface
type Bank struct {
}

//deposit
func (b *Bank) Deposit() {
	fmt.Println("存款成功")
}

//Withdrawal
func (b *Bank) Withdraw() {
	fmt.Println("取款成功")
}

//Transfer
func (b *Bank) Transfer() {
	fmt.Println("转账成功")
}

//We can define another Alipay bank interface
type Alipay struct {
}

//deposit
func (a *Alipay) Deposit() {
	fmt.Println("支付宝存款成功")
}

//Withdrawal
func (a *Alipay) Withdraw() {
	fmt.Println("Alipay withdrawal successful")
}

//Transfer
func (a *Alipay) Transfer() {
	fmt.Println("Alipay transfer successful")
}

//Implement an abstraction layer to isolate the different implementation layers so that new implementation layers can be added without modifying the original code, which is the open-close principle
func BankBusiness(bank Banker) {
	bank.Deposit()
}

func main() {
	//The business of deposits
	BankBusiness(&Bank{})
	BankBusiness(&Alipay{})
}

🚀 编译结果如下:

[Running] go run "d:\文档\最近的\awesome-golang\docs\code\go-super\80-main.go"
存款成功
支付宝存款成功

END 链接