首頁  >  文章  >  後端開發  >  go語言不支援aop嗎

go語言不支援aop嗎

青灯夜游
青灯夜游原創
2022-12-27 17:04:524227瀏覽

go語言支援aop。 AOP是指面向切面編程,是透過預編譯方式和運行期間動態代理實現程序功能的統一維護的一種技術;AOP是面向對像中的一種方式,主要應用場景:日誌記錄,性能統計,安全控制,事務處理,異常處理等等。

go語言不支援aop嗎

本教學操作環境:windows7系統、GO 1.18版本、Dell G3電腦。

什麼是aop?

在軟體業,AOP為Aspect Oriented Programming的縮寫,意為:面向切面編程,透過預編譯方式和運行期間動態代理實現程序功能的統一維護的一種技術。 AOP是OOP的延續,是軟體開發中的熱點,也是Spring框架中的重要內容,是函數式程式設計的衍生範式。利用AOP可以對業務邏輯的各個部分進行隔離,從而使得業務邏輯各部分之間的耦合度降低,提高程序的可重用性,同時提高了開發的效率。

面向切面程式設計是物件導向中的一種方式而已。在程式碼執行過程中,動態嵌入其他程式碼,叫做面向切面程式設計。常見的使用場景:

  • 日誌

  • #事物

  • ##資料庫操作

面向切面編程,就是將交叉業務邏輯封裝成切面,利用AOP的功能將切面織入到主業務邏輯中。所謂交叉業務邏輯是指,通用的,與主業務邏輯無關的程式碼,如安全檢查,事物,日誌等。若不使用AOP,則會出現程式碼糾纏,即交叉業務邏輯與主業務邏輯混合在一起。這樣,會使業務邏輯變得混雜不清。

主要應用場景:日誌記錄,效能統計,安全控制,事務處理,異常處理等等。

核心概念

  • #JoinPoint:連接點。是程式執行中的一個精確執行點,例如類別中的一個方法。

  • PointCut:切入點。指定哪些組件的哪些方法使用切面組件。

  • Advice:通知,用於指定具體作用的位置,是方法之前或之後等等,分為前置通知,後置通知,異常通知,返回通知,環繞通知。

  • Aspect: 切面。封裝通用業務邏輯的元件,也就是我們想要插入的程式碼內容。

其內在設計模式為代理模式。

go語言支不支援aop?

go語言支援aop。

Go實作AOP的範例:

// User 
type User struct {
	Name string
	Pass string
}

// Auth 验证
func (u *User) Auth() {
	// 实际业务逻辑
	fmt.Printf("register user:%s, use pass:%s\n", u.Name, u.Pass)
}


// UserAdvice 
type UserAdvice interface {
    // Before 前置通知
    Before(user *User) error
    
    // After 后置通知
	After(user *User)
}

// ValidatePasswordAdvice 用户名验证
type ValidateNameAdvice struct {
}

// ValidatePasswordAdvice 密码验证
type ValidatePasswordAdvice struct {
	MinLength int
	MaxLength int
}

func (ValidateNameAdvice) Before(user *User) error {
	fmt.Println("ValidateNameAdvice before")
	if user.Name == "admin" {
		return errors.New("admin can't be used")
	}

	return nil
}

func (ValidateNameAdvice) After(user *User) {
	fmt.Println("ValidateNameAdvice after")
	fmt.Printf("username:%s validate sucess\n", user.Name)
}

// Before 前置校验
func (advice ValidatePasswordAdvice) Before(user *User) error {
	fmt.Println("ValidatePasswordAdvice before")
	if user.Pass == "123456" {
		return errors.New("pass isn't strong")
	}

	if len(user.Pass) > advice.MaxLength {
		return fmt.Errorf("len of pass must less than:%d", advice.MaxLength)
	}

	if len(user.Pass) < advice.MinLength {
		return fmt.Errorf("len of pass must greater than:%d", advice.MinLength)
	}

	return nil
}

func (ValidatePasswordAdvice) After(user *User) {
	fmt.Println("ValidatePasswordAdvice after")
	fmt.Printf("password:%s validate sucess\n", user.Pass)
}

// UserAdviceGroup,通知管理组
type UserAdviceGroup struct {
	items []UserAdvice
}

// Add 注入可选通知
func (g *UserAdviceGroup) Add(advice UserAdvice) {
	g.items = append(g.items, advice)
}

func (g *UserAdviceGroup) Before(user *User) error {
	for _, item := range g.items {
		if err := item.Before(user); err != nil {
			return err
		}
	}

	return nil
}

// After
func (g *UserAdviceGroup) After(user *User) {
	for _, item := range g.items {
		item.After(user)
	}
}

// UserProxy 代理,也是切面
type UserProxy struct {
	user *User
}

// NewUser return UserProxy
func NewUser(name, pass string) UserProxy {
	return UserProxy{user:&User{Name:name, Pass:pass}}
}

// Auth 校验,切入点
func (p UserProxy) Auth() {
	group := UserAdviceGroup{}
	group.Add(&ValidatePasswordAdvice{MaxLength:10, MinLength:6})
    group.Add(&ValidateNameAdvice{})
    
    // 前置通知
	if err := group.Before(p.user); err != nil {
		panic(err)
	}

    // 实际逻辑
	p.user.Auth()

    // 后置通知
	group.After(p.user)

}

使用AOP模式進行解耦,分離主業務與副業務。其實就那樣。

【相關推薦:

Go影片教學程式設計教學

以上是go語言不支援aop嗎的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn