不知道为什么,那么多设计模式里面,对代理模式有一种特别的喜欢。很是喜欢这种切面的思维,将多个相似方法的共同前置和后置抽象出来的实现,真的是觉得很棒。这半年转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"));
}
}
结果:
代码就不分析了,代理模式在之前的文章有提到,这里有传送门
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要实现这种切面的动作,也就那么几行代码,然后来看下测试结果
后记:各个语言有各个语言的特性,一种语言的某个算法实现,换成另一种语言,也有可能,要换一个思路实现,不应该只得其形。