定义
代理模式,是一种结构型设计模式,它提供了对另外一个对象的代理或占位符,以控制对这个对象的访问。
使用代理模式可以在不改变被代理对象的前提下,为客户端和被代理对象之间提供一个中介,并进行一些操作,如访问控制,延迟初始化,日志等。
UML 类图
typescript 实现
1. 定义主题接口
interface Subject {
operation(): void;
}
2. 创建真实主题类
class RealSubject implements Subject {
public operation(): void {
console.log("RealSubject: Handling operation.");
}
}
3. 创建代理类
class Proxy implements Subject {
private realSubject: RealSubject;
constructor(realSubject: RealSubject) {
this.realSubject = realSubject;
}
public operation(): void {
if(this.checkAccess()) {
this.realSubject.operation();
this.logAccess();
}
}
private checkAccess(): boolean {
console.log('Proxy: Checking access before firing a real operation.');
return true;
}
private logAccess(): void {
console.log('Proxy: Logging the time of operation.');
}
}
4. 使用示例
function clientCode(subject: Subject) {
subject.operation();
}
console.log("Client: Executing the client code with a real subject:");
const realSubject = new RealSubject();
clientCode(realSubject);
console.log("");
console.log("Client: Executing the same client code with a proxy:");
const proxy = new Proxy(realSubject);
clientCode(proxy);
通用实现
// 公共代码,缓存代理
export function createCacheProxyFactory<T extends (...args: any[]) => any>(fn: T): T {
const cache = new Map<string, any>();
const isProxySupported = () => {
return typeof Proxy !== 'undefined';
}
if(isProxySupported()) {
return new Proxy(fn, {
apply(target: T, thisArg, args: any[]) {
const key = JSON.stringify(args);
if(cache.has(key)) {
return cache.get(key);
} else {
const result = Reflect.apply(target, thisArg, args);
cache.set(key, result);
return result;
}
}
})
} else {
return function(...args: any[]) {
const key = JSON.stringify(args);
if(cache.has(key)) {
return cache.get(key);
} else {
const result = fn(...args);
cache.set(key, result);
return result;
}
} as T;
}
}
// 私有代码,使用示例
// 这个函数计算比较耗时,我们对此进行暂存计算结果
const expensiveFunction = (arg: number) => {
return arg * 100;
}
const cachedExpensiveFunction = createCahceProxyFactory(expensiveFunction);
cachedExpensiveFunction(5);