代理模式
本篇博客将介绍代理模式,代理模式是常用的结构型设计模式之一,当用户无法直接访问某个对象或者访问某个对象存在困难时,可以通过一个代理对象来间接访问,为了保证客户端使用的透明性,所访问的真实对象和代理对象会使用相同的接口。
模式分类
结构型设计模式。
模式产生得原因
在软件开发中,由于某些原因,我们不想或者不能直接访问一个对象,此时我们可以通过一个被称为代理的第三者来实现间接访问,这就是代理模式。代理对象在客户端和目标对象之间会起到中介的作用,他去掉客户不想看到的内容和服务或者增添客户需要的额外的新服务。
模式灵感的来源
近年来,代购已逐步成为电子商务的一个重要分支。代购就是找人帮忙购买所需要的商品,用户可能不能直接接触到所需要的商品,比如这个商品本地没有后者只有海外才有,或者说用户不想自己去买于是就呼叫代购来帮自己到某某某超市购买一些物品,这些都是代购,而这种用户不能或者不想直接购买商品的行为,就被抽象成了代理模式。
模式类图
由上图可知,代理模式分为3个对象:
Subject(抽象主题角色):
它声明了真实主题角色和代理主题角色的共同接口,这样客户端只需要根据抽象主题接口进行编程即可。
Proxy(代理主题角色):
代理主题角色包含一个对于真实主题角色的引用的维护,当客户端要调用一些方法时,代理主题角色将会调用真实主题角色中的同名方法。当然代理主题角色中是可以添加额外操作的。例如在保护代理中,代理角色就需要对访问真是主题的请求做甄别。
ConcreteSubject(真实主题角色):
它定义了代理角色所代表的真实对象,在真实对象中实现了真实的业务操作,客户端通过代理角色间接调用真实角色中的业务逻辑。
代码实现
例子:在一个论坛中已注册的用户和游客的权限不同,已注册的用户拥有发帖,修改自己的注册信息,修改自己帖子等功能,而游客只能查看别人发的帖子,没有其他权限,使用代理模式设计论坛的权限管理模块。
User用户基类:
namespace Proxy.Proxy.Question6
{
public abstract class User
{
public string Name;
public string Right;
public User(string name, string right)
{
Name = name;
Right = right;
}
public abstract void Look();
public virtual void Post(){
}
public virtual void ModifyContent(){
}
public virtual void ModifyInfo(){
}
}
}
IMember会员接口:
namespace Proxy.Proxy.Question6
{
public interface IMember
{
void Post();
void ModifyContent();
void ModifyInfo();
}
}
Proxy用户代理类:这里代理使用了虚拟代理的思想,延迟到使用时在创建真实的用户类,这里由于功能比较基础,所以就将逻辑都写在了代理类中,实际上应该将真实逻辑分摊在真实对象上。
using System;
using System.Diagnostics;
namespace Proxy.Proxy.Question6
{
public class Proxy : User
{
private User _user;
private bool _isMember;
public override void Look()
{
_user.Look();
}
public override void Post()
{
if (!_isMember)
{
Console.WriteLine($"无权使用此功能");
return;
}
_user.Post();
Console.WriteLine($"{
_user.Name}用户使用Post功能");
}
public override void ModifyContent()
{
if (!_isMember)
{
Console.WriteLine($"无权使用此功能");
return;
}
_user.ModifyContent();
Console.WriteLine($"{
_user.Name}用户使用ModifyContent功能");
}
public override void ModifyInfo()
{
if (!_isMember)
{
Console.WriteLine($"无权使用此功能");
return;
}
_user.ModifyInfo();
Console.WriteLine($"{
_user.Name}用户使用ModifyInfo功能");
}
public Proxy(string name, string right) : base(name, right)
{
if (right.Equals("Member"))
{
_user = new Member(name, right);
_isMember = true;
}
else
{
_user = new Custom(name,right);
}
}
}
}
Custom游客类:
namespace Proxy.Proxy.Question6
{
public class Custom : User
{
public override void Look()
{
}
public Custom(string name, string right) : base(name, right)
{
}
}
}
Member会员类:
namespace Proxy.Proxy.Question6
{
public class Member : User, IMember
{
public override void Look()
{
}
public override void Post()
{
}
public override void ModifyContent()
{
}
public override void ModifyInfo()
{
}
public Member(string name, string right) : base(name, right)
{
}
}
}
代理模式总结
代理模式的优点:
- 代理模式能够协调调用者和被调用者,在一定程度上降低系统的耦合性。
- 客户端可以针对抽象主题角色进行编程,增加和更换代理类无需改变源代码,系统具有较好的灵活性和可拓展性。
代理模式的缺点:
- 由于在客户端和真实主题之间增加了代理角色,因此有些类型的代理模式可能会造成处理速度变慢。
- 实现代理模式需要额外的工作,而有些代理模式的实现过程较为复杂,比如远程代理。