-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
295 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package auth_hook | ||
|
||
import ( | ||
"fmt" | ||
"github.com/practice/Design-Patterns-practice/other/create-resource-pattern/resource" | ||
) | ||
|
||
// AuthHook 是身份验证的钩子实现 | ||
type AuthHook struct { | ||
Username string | ||
Password string | ||
} | ||
|
||
// BeforeCreate 在创建资源之前执行的钩子函数 | ||
func (h *AuthHook) BeforeCreate(resource *resource.Resource) error { | ||
// 模拟身份验证逻辑 | ||
if h.Username != "admin" || h.Password != "password" { | ||
return fmt.Errorf("authentication failed") | ||
} | ||
return nil | ||
} | ||
|
||
// AfterCreate 在创建资源之后执行的钩子函数 | ||
func (h *AuthHook) AfterCreate(resource *resource.Resource) error { | ||
fmt.Printf("Resource with ID %s created successfully\n", resource.ID) | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package hook | ||
|
||
import "github.com/practice/Design-Patterns-practice/other/create-resource-pattern/resource" | ||
|
||
// ResourceHook 创建资源时的钩子方法 | ||
type ResourceHook interface { | ||
BeforeCreate(resource *resource.Resource) error | ||
AfterCreate(resource *resource.Resource) error | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package log_hook | ||
|
||
import ( | ||
"github.com/practice/Design-Patterns-practice/other/create-resource-pattern/resource" | ||
"log" | ||
) | ||
|
||
// LoggingHook 是日志记录的钩子实现 | ||
type LoggingHook struct { | ||
Logger *log.Logger | ||
} | ||
|
||
// BeforeCreate 在创建资源之前执行的钩子函数 | ||
func (h *LoggingHook) BeforeCreate(resource *resource.Resource) error { | ||
h.Logger.Printf("Creating resource with ID: %s\n", resource.ID) | ||
return nil | ||
} | ||
|
||
// AfterCreate 在创建资源之后执行的钩子函数 | ||
func (h *LoggingHook) AfterCreate(resource *resource.Resource) error { | ||
h.Logger.Printf("Resource with ID %s created successfully\n", resource.ID) | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package validator_hook | ||
|
||
import ( | ||
"fmt" | ||
"github.com/practice/Design-Patterns-practice/other/create-resource-pattern/resource" | ||
"regexp" | ||
) | ||
|
||
// EmailValidatorHook 是电子邮件验证的钩子实现 | ||
type EmailValidatorHook struct { | ||
EmailRegex *regexp.Regexp | ||
} | ||
|
||
// BeforeCreate 在验证用户之前执行的钩子函数 | ||
func (h *EmailValidatorHook) BeforeCreate(resource *resource.Resource) error { | ||
if !h.EmailRegex.MatchString(resource.Email) { | ||
return fmt.Errorf("invalid email address") | ||
} | ||
return nil | ||
} | ||
|
||
// AfterCreate 在验证用户之后执行的钩子函数 | ||
func (h *EmailValidatorHook) AfterCreate(resource *resource.Resource) error { | ||
fmt.Printf("User with ID %s validated successfully\n", resource.ID) | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
package create_resource_pattern | ||
|
||
import ( | ||
"fmt" | ||
"github.com/practice/Design-Patterns-practice/other/create-resource-pattern/hook" | ||
"github.com/practice/Design-Patterns-practice/other/create-resource-pattern/resource" | ||
"sync" | ||
) | ||
|
||
// ResourceManager 是资源对象的管理器 | ||
type ResourceManager struct { | ||
mu sync.Mutex | ||
resources map[string]*resource.Resource | ||
beforeFn []func(resource *resource.Resource) error | ||
afterFn []func(resource *resource.Resource) error | ||
} | ||
|
||
// NewResourceManager 创建一个新的资源管理器 | ||
func NewResourceManager() *ResourceManager { | ||
return &ResourceManager{ | ||
resources: make(map[string]*resource.Resource), | ||
} | ||
} | ||
|
||
// RegisterHook 注册资源对象的钩子 | ||
func (rm *ResourceManager) RegisterHook(hook hook.ResourceHook) { | ||
rm.beforeFn = append(rm.beforeFn, hook.BeforeCreate) | ||
rm.afterFn = append(rm.afterFn, hook.AfterCreate) | ||
} | ||
|
||
// CreateResource 创建一个新的资源对象 | ||
func (rm *ResourceManager) CreateResource(id, name, email string) error { | ||
rm.mu.Lock() | ||
defer rm.mu.Unlock() | ||
|
||
var err error | ||
// 如果 hook 流程出错,默认不创建资源对象 | ||
defer func() { | ||
if err != nil { | ||
delete(rm.resources, id) | ||
} | ||
}() | ||
|
||
if _, exists := rm.resources[id]; exists { | ||
return fmt.Errorf("resource with ID %s already exists", id) | ||
} | ||
|
||
rr := &resource.Resource{ | ||
ID: id, | ||
Name: name, | ||
Email: email, | ||
// 设置其他属性... | ||
} | ||
|
||
// 执行创建前的钩子函数 | ||
for _, beforeFn := range rm.beforeFn { | ||
err = beforeFn(rr) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
|
||
rm.resources[id] = rr | ||
|
||
// 执行创建后的钩子函数 | ||
for _, afterFn := range rm.afterFn { | ||
err = afterFn(rr) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// GetResourceByID 根据资源 ID 获取资源对象 | ||
func (rm *ResourceManager) GetResourceByID(id string) (*resource.Resource, error) { | ||
rm.mu.Lock() | ||
defer rm.mu.Unlock() | ||
|
||
r, exists := rm.resources[id] | ||
if !exists { | ||
return nil, fmt.Errorf("resource with ID %s does not exist", id) | ||
} | ||
|
||
return r, nil | ||
} | ||
|
||
func (rm *ResourceManager) DeleteResourceByID(id string) error { | ||
rm.mu.Lock() | ||
defer rm.mu.Unlock() | ||
|
||
delete(rm.resources, id) | ||
return nil | ||
} | ||
|
||
// ListResources 返回所有资源对象的列表 | ||
func (rm *ResourceManager) ListResources() []*resource.Resource { | ||
rm.mu.Lock() | ||
defer rm.mu.Unlock() | ||
|
||
resources := make([]*resource.Resource, 0, len(rm.resources)) | ||
for _, r := range rm.resources { | ||
resources = append(resources, r) | ||
} | ||
|
||
return resources | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package create_resource_pattern | ||
|
||
import ( | ||
"fmt" | ||
"github.com/practice/Design-Patterns-practice/other/create-resource-pattern/hook/auth_hook" | ||
"github.com/practice/Design-Patterns-practice/other/create-resource-pattern/hook/log_hook" | ||
"github.com/practice/Design-Patterns-practice/other/create-resource-pattern/hook/validator_hook" | ||
"log" | ||
"regexp" | ||
"testing" | ||
) | ||
|
||
func TestResourceManager(t *testing.T) { | ||
rm := NewResourceManager() | ||
|
||
// 创建一个身份验证钩子对象 | ||
authHook := &auth_hook.AuthHook{ | ||
Username: "admin", | ||
Password: "password", | ||
} | ||
|
||
// 注册身份验证钩子 | ||
rm.RegisterHook(authHook) | ||
|
||
// 创建一个日志记录钩子对象 | ||
logger := log.New(log.Writer(), "", log.LstdFlags) | ||
loggingHook := &log_hook.LoggingHook{ | ||
Logger: logger, | ||
} | ||
|
||
// 注册日志记录钩子 | ||
rm.RegisterHook(loggingHook) | ||
|
||
// 创建一个电子邮件验证钩子对象 | ||
emailRegex := regexp.MustCompile(`^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$`) | ||
|
||
emailValidator := &validator_hook.EmailValidatorHook{ | ||
EmailRegex: emailRegex, | ||
} | ||
|
||
rm.RegisterHook(emailValidator) | ||
|
||
err := rm.CreateResource("1", "Resource 1", "[email protected]") | ||
if err != nil { | ||
fmt.Println("Error creating resource:", err) | ||
return | ||
} | ||
|
||
err = rm.CreateResource("2", "Resource 2", "[email protected]") | ||
if err != nil { | ||
fmt.Println("Error创建资源:", err) | ||
return | ||
} | ||
|
||
resources := rm.ListResources() | ||
fmt.Println("Resources:") | ||
for _, resource := range resources { | ||
fmt.Printf("ID: %s, Name: %s\n", resource.ID, resource.Name) | ||
} | ||
|
||
resource, err := rm.GetResourceByID("1") | ||
if err != nil { | ||
fmt.Println("Error getting resource:", err) | ||
return | ||
} | ||
|
||
err = rm.DeleteResourceByID("1") | ||
if err != nil { | ||
fmt.Println("Error deleting resource:", err) | ||
return | ||
} | ||
|
||
fmt.Println("Resource 1 Name:", resource.Name) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package resource | ||
|
||
// Resource 是一个示例资源对象 | ||
type Resource struct { | ||
ID string | ||
Name string | ||
Email string | ||
// 添加其他属性... | ||
} |