考虑这样一种情况。某个系统要根据用户的权限来判断是否能操作。那么可以这么写:
class ViewAction{
String permission;
public ViewAction(String permission ){
this.permission = permission;
}
public void DoAction(){
if(permission.equals("VIEW")){
System.out.println("查看信息!");
}
}
}
class AddAction{
String permission;
public AddAction(String permission ){
this.permission = permission;
}
public void DoAction(){
if(permission.equals("ADD")){
System.out.println("添加信息!");
}
}
}
public class proxy {
public static void main(String[] args){
//赋予用户查看权限
String permission = "VIEW";
ViewAction user = new ViewAction(permission);
user.DoAction();
AddAction user1 = new AddAction(permission);
user1.DoAction();
}
}
可以看到,虽然执行了添加 查看操作,可是最后只执行了查看操作。
但是这样子将权限和操作放在一起,违反了类的单一性原则。不利用程序维护。
既然有这么多的问题,我们有必要对该类进行重新设计。其实大家早已想到,这个类应该使用代理模式。和我们买火车票的动作一样,动作类不能直接执行那个动作,而是要先检查权限,然后才能执行;先检查权限,后执行的那各类其实就是一个代理类,修改后的代码如下:
interface Action{
public void DoAction();
}
class ViewAction implements Action{
public void DoAction(){
System.out.println("查看信息!");
}
}
class AddAction implements Action{
public void DoAction(){
System.out.println("添加信息!");
}
}
class ProxyViewAction implements Action {
private Action action = null;
private User user = new User() ;
public ProxyViewAction(Action act) {
action = act;
}
public void DoAction() {
// 调用权限类的方法取得用户权限
if (user.getPermission().equals("VIEW")) {
action.DoAction();
}
}
}
//用户信息
class User{
private String permission = "VIEW" ;
public String getPermission() {
return permission;
}
public void setPermission(String permission) {
this.permission = permission;
}
}
public class proxy {
public static void main(String[] args){
ProxyViewAction proxy = new ProxyViewAction(new ViewAction());
proxy.DoAction();
//将用户信息的权限变成ADD,则上面的方法不能执行。
}
}
在我们的ProxyViewAction类中,除了做了客户真正想要做的动作:DoAction()以外,还进行了额外的动作检查用户的权限。而作核心动 作DoAction()是在一个干干净净的类:ViewAction中进行,这个类只做核心动作,对其他的不关心,满足了单一职责原则。
客户端通过调用代理类来执行动作,而代理类一是将权限判断和动作的执行分离开来,满足了单一职责原则
代理又被称为委派,说的是代理类并不真正的执行那个核心动作,而是委派给另外一个类去执行,如ProxyView类中,ProxyView类并没有真正执行doAction()方法,而是交给ViewAction类去执行。
我们再来看代理类ProxyViewAction,可以看到它不仅依赖于接口Action,而且依赖于具体的实现ViewAction。这样对我们的系统 扩展很不利,比如我们有Add动作、Delete动作、Modify动作等等,我们需要对每一个动作都写一个代理类,而这些代理类都做同样的事情,先进行 权限判断,然后再委派。所以我们需要对这些代理再进行一次抽象,让它只依赖接口Action,而不依赖于具体的实现。 要实现这样的想法,我们需要将代理类中的具体实现提走,让代理的使用者在运行期提供具体的实现类,即所谓的依赖注入,代码如下
interface Action{
public void DoAction();
}
class ViewAction implements Action{
public void DoAction(){
System.out.println("查看信息!");
}
}
class AddAction implements Action{
public void DoAction(){
System.out.println("添加信息!");
}
}
class ProxyAction implements Action {
private Action action = null;
private User user = new User() ;
public ProxyAction(Action act) {
action = act;
}
public void DoAction() {
// 调用权限类的方法取得用户权限
if (user.getPermission().equals(action.getClass().getSimpleName())) {
action.DoAction();
}
}
}
//用户信息
class User{
private String permission = "ViewAction" ;
public String getPermission() {
return permission;
}
public void setPermission(String permission) {
this.permission = permission;
}
}
public class proxy {
public static void main(String[] args){
Action action = new ProxyAction(new ViewAction());
action.DoAction();
//将用户信息的权限变成AddView,则上面的方法不能执行。
}
}
这样,我们就将所有实现了Action接口的实现使用一个代理类来代理它们。除了ViewAction类能用,以后扩展的AddAction、 ModifyAction、DeleteAction类等等,都可以使用一个代理类:ProxyAction。