エージェントモードの運用


このような状況を考える.あるシステムは、ユーザーの権限に基づいて操作できるかどうかを判断します.では、次のように書くことができます.
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();
	  }
}

表示の追加操作が実行されたが、最後に表示操作のみが実行されたことがわかります.
 
しかし,このように権限と操作を一緒にすることは,クラスの単一性の原則に反する.プログラムメンテナンスを利用しない.
 
こんなに多くの問題がある以上、このクラスを再設計する必要があります.実は、このクラスはエージェントモードを使うべきだととっくに考えています.私たちが汽車の切符を買う動作と同じように、動作類は直接その動作を実行するのではなく、まず権限を検査してから実行しなければならない.まず権限をチェックして、それから実行する各種類は実は1つのエージェントクラスで、修正したコードは以下の通りです:
 
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, 。
	  }
}

私たちのProxyView Actionクラスでは、お客様が本当にやりたいアクション:DoAction()のほかに、ユーザーの権限をチェックする追加のアクションが行われています.コアアクションDoAction()はきれいなクラス:ViewActionで行われ、このクラスはコアアクションだけを行い、他のことに関心を持たず、単一の職責原則を満たしています.
 
クライアントはエージェントクラスを呼び出すことで動作を実行するが,エージェントクラス1は権限判断と動作の実行を分離し,単一の職責原則を満たす.
 
エージェントは委任とも呼ばれ、エージェントクラスがそのコア動作を本当に実行するのではなく、ProxyViewクラスのような別のクラスに委任して実行するということです.ProxyViewクラスでは、ProxyViewクラスはdoAction()メソッドを本当に実行するのではなく、View Actionクラスに実行させます.
 
エージェントクラス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を使用できます.
 
クライアントは次のようになります.
Action action = new ProxyAction(new ViewAction());
action.DoAction();
エージェントクラスへの依存注入により,エージェントクラスに一定の拡張性を初歩的に与えた.しかし、このエージェントクラスは特定のインタフェースに依存していることも見られます.これは依然として私达の実际の要求を満たすことができなくて、例えば私达のシステムの権限の制御は一般的に全体のシステムのレベルで、このようにシステムのレベルの権限の制御、私达は全体のシステムの中で1つの统一的なインタフェースを抽象化することが难しくて、多くのインタフェースがあるかもしれなくて、上の代理のモードによって、私达はすべてのインタフェースに対して1つの代理のクラスを书く必要があって、同様に、これらの类の机能はすべて同じですこれは明らかに良い解決策ではない.
以上の理由に基づいて,システムが統一されたインタフェースを持たない場合に,いくつかのばらばらなオブジェクトのいくつかの動作に対してエージェントモードを使用する問題を解決する必要がある.JAVA APIは、動的エージェントまたは動的委任の技術を導入しています.