在Golang進化的代理模式

liangxingwei發表於2017-12-14

不知道為什麼,那麼多設計模式裡面,對代理模式有一種特別的喜歡。很是喜歡這種切面的思維,將多個相似方法的共同前置和後置抽象出來的實現,真的是覺得很棒。這半年轉golang開發之後,終於在前段時間折騰出了golang風格的代理模式--其實已經不是代理模式了,更貼切的說法應該叫Golang的小技巧之一

沒有對比就沒有差距的體現,用go和Java實現一個插入新使用者的demo

Java風格

先看下在Java裡面的實現

UserService介面:
public interface UserService {	
	void save(User user);
}

UserServiceProxy代理類:
public class UserServiceProxy implements UserService{
	private UserService userService;
	public UserServiceProxy(UserService userService) {
		super();
		this.userService = userService;
	}
	@Override
	public void save(User user) {
		System.out.println("--------開啟事務--------");
		userService.save(user);
		System.out.println("--------結束事務--------");
	}
}

UserServiceImpl業務類:
public class UserServiceImpl implements UserService {
	@Override
	public void save(User user) {
		System.out.println("儲存使用者"+user);
	}
}

User實體類:
public class User {
	private String name;
	public User(String name) {
		this.name = name;
	}
	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append("User [name=").append(name).append("]");
		return builder.toString();
	}
}

測試類:
public class Main {
	public static void main(String[] args) {
		UserServiceProxy proxy = new UserServiceProxy(new UserServiceImpl());
		proxy.save(new User("sivan"));
	}
}
複製程式碼

結果:

Java的實現
程式碼就不分析了,代理模式在之前的文章有提到,這裡有傳送門

Golang風格

Golang因為有一個函式變數形參的特性,註定了要實現類似代理模式這種抽象前置和後置動作的操作,不需要那麼繁雜

package main

import (
	"fmt"
)

func main() {
	saveUser(&user{"sivan"})
}

type user struct {
	Name string
}

func (u *user) String() string {
	return u.Name
}

func saveUser(user *user) {
	withTx(func() {
		fmt.Printf("儲存使用者 %s\n", user.Name)
	})
}

func withTx(fn func()) {
	fmt.Println("開啟事務")
	fn()
	fmt.Println("結束事務")
}
複製程式碼

是的,你沒看錯,go要實現這種切面的動作,也就那麼幾行程式碼,然後來看下測試結果

精簡但不失力量的go實現

後記:各個語言有各個語言的特性,一種語言的某個演算法實現,換成另一種語言,也有可能,要換一個思路實現,不應該只得其形。

實力不足,難免有錯,還請評論區指正。

相關文章