這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
不知道為什麼,那麼多設計模式裡面,對代理模式有一種特別的喜歡。很是喜歡這種切面的思維,將多個相似方法的共同前置和後置抽象出來的實現,真的是覺得很棒。這半年轉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 mainimport ( "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實現
後記:各個語言有各個語言的特性,一種語言的某個演算法實現,換成另一種語言,也有可能,要換一個思路實現,不應該只得其形。
實力不足,難免有錯,還請評論區指正。