javaデザインモード-プロキシモード(実例解説)
プロキシモードはjavaの最も一般的な設計モードの一つである。springのaopは代理モードを使っています。
一般的に、プロキシモードは、静的エージェントと動的エージェントの2つに分類される。
構造類の設計モードとしては、クラスの内部コードを修正しない場合に、クラスを開拓することが作用しており、継承メカニズムの一種である。
eg:以下、ユーザ登録という例について、プロキシモードを実現します。
基本的な需要は、ユーザーのログインとニックネーム機能の変更を実現することです。
上のコードは、まずIUserインターフェースとuser実装クラスです。
エージェントクラスを追加して、エージェントクラスに「ユーザーの行動を記録する」という機能を書けばいいです。クラスを変更しないで、カテゴリだけを広げて、エラーの発生を減らすことができます。
これは困惑して、すべての役はすべて1つの静的な代理種類を建てて、種類は爆発しました。急がないです。私たちはダイナミックエージェントモードがあります。
ダイナミックプロキシモードは自分でプロキシ類を新築しなくてもいいです。具体的な実現類(主体)を彼に伝えてください。彼はデフォルトであなたにプロキシ類を生成しました。
本質的には、Javaの反射機構を利用して、動作時に、対応するプロキシクラスを動的に生成する。
反射がないと、ダイナミックエージェントがありません。
1.静的エージェントモードは比較的簡単であり、各実装クラス(subject本体)に対して、aopの制御など、エンティティクラス(subject本体)の参照があるエージェントクラスを新規に作成することができる。
2.静的エージェントには限界があり、各エンティティ類に対して静的エージェントを新規に作成する必要があり、このようにして静的エージェントが多すぎる場合があり、動的エージェントが生まれてきた。
3.動的エージェントは、具体的な実装クラス(subject本体)に限定されず、その内部では、Objectを用いてエンティティ類の参照にアクセスし、反射を利用してそのエンティティ類の様々な方法を獲得し、クラス(subject本体)を実現するための切断面AOPプログラミング制御を実現する。
4.上記の書き方はJDKのダイナミックエージェントであり、特に完璧ではない。このような動的エージェントはエンティティクラスが少なくとも一つのインターフェースを実現する必要があるからだ。問題はすべての種類にインターフェースがあるわけではないので、ここで完璧ではないです。
以上は私自身の代理モデルに対する理解です。もし間違いがあれば、ご指摘をお願いします。ありがとうございます。
以上のjavaデザインモード-プロキシモード(実例解説)は、小編集が皆さんに提供した内容の全部を共有しています。参考にしていただければと思います。どうぞよろしくお願いします。
一般的に、プロキシモードは、静的エージェントと動的エージェントの2つに分類される。
構造類の設計モードとしては、クラスの内部コードを修正しない場合に、クラスを開拓することが作用しており、継承メカニズムの一種である。
eg:以下、ユーザ登録という例について、プロキシモードを実現します。
基本的な需要は、ユーザーのログインとニックネーム機能の変更を実現することです。
上のコードは、まずIUserインターフェースとuser実装クラスです。
public interface IUser {
//
void login(String userId,String password);
//
void editNickname(String nickname);
}
public class User implements IUser {
private String nickname;
private String userId;
private String password;
public User(String userId,String password){
this.userId = userId;
this.password = password;
}
@Override
public void login(String userId, String password){
if(this.userId == userId && this.password == password){
System.out.println(" ");
}
else
System.out.println(" ");
}
@Override
public void editNickname(String nickname) {
this.nickname = nickname;
System.out.println(" , :"+this.nickname);
}
}
クライアントクラス
public class Client {
public static void main(String[] args) {
//
IUser user = new User("firs","123");
user.login("firs", "123");
user.editNickname(" ");
}
やはりとても簡単です。しかし、後の製品マネージャーから、ユーザーの行動を記録する機能を追加する必要があります。どうすればいいですか?ユーザークラスを直接修正しますか?いいえ、代理モードを使います。エージェントクラスを追加して、エージェントクラスに「ユーザーの行動を記録する」という機能を書けばいいです。クラスを変更しないで、カテゴリだけを広げて、エラーの発生を減らすことができます。
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* ,
* @author Administrator
*
*/
public class StaticProxy implements IUser {
private IUser user;
public StaticProxy(String userId,String password){
this.user = new User(userId,password);
}
// ,
void noteLoginInfo(String[] params, String opreate){
Map<String,Object> loginInfo = new HashMap<>();
loginInfo.put("params", params);
loginInfo.put("opreate", opreate);
loginInfo.put("opreateTime", new Date());
System.out.println(" ");
}
@Override
public void login(String userId, String password){
noteLoginInfo(new String[]{userId, password},"login");
user.login(userId, password);
}
@Override
public void editNickname(String nickname) {
noteLoginInfo(new String[]{nickname},"editNickname");
user.editNickname(nickname);
}
}
クライアントクラス:
public class Client {
public static void main(String[] args) {
//
IUser user = new User("firs","123");
user.login("firs", "123");
user.editNickname(" ");
System.out.println("");
System.out.println("============= ===========");
//
// “ , ” ,
IUser proxy = new StaticProxy("firs","123");
proxy.login("firs", "123");
proxy.editNickname(" ");
}
このようにクライアントクラスを修正して、静的なエージェントを追加すればいいです。完璧に実現します。しかし、需要は無限です。製品の管理人があなたに言いました。「私たちは管理人の役を増やしました。二級管理人もいます。」これは困惑して、すべての役はすべて1つの静的な代理種類を建てて、種類は爆発しました。急がないです。私たちはダイナミックエージェントモードがあります。
ダイナミックプロキシモードは自分でプロキシ類を新築しなくてもいいです。具体的な実現類(主体)を彼に伝えてください。彼はデフォルトであなたにプロキシ類を生成しました。
本質的には、Javaの反射機構を利用して、動作時に、対応するプロキシクラスを動的に生成する。
反射がないと、ダイナミックエージェントがありません。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
*
* @author Administrator
*
*/
public class DynamicProxy implements InvocationHandler {
private Object object;
public DynamicProxy(String userId,String password,Class<?> c){
Object obj = null;
try {
obj = Class.forName(c.getName())
.getConstructor(String.class,String.class)
.newInstance(userId,password);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.object = obj;
}
// ,
void noteLoginInfo(String[] params, String opreate){
Map<String,Object> loginInfo = new HashMap<>();
loginInfo.put("params", params);
loginInfo.put("opreate", opreate);
loginInfo.put("opreateTime", new Date());
System.out.println(" ");
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
String[] params = new String[args.length];
for(int i = 0 ;i < args.length ; i++){
params[i] = args[i].toString();
}
noteLoginInfo(params, method.getName());
return method.invoke(object, args);
}
}
最後のクライアントクラス:
package com.test.my;
import java.lang.reflect.Proxy;
public class Client {
public static void main(String[] args) {
//
IUser user = new User("firs","123");
user.login("firs", "123");
user.editNickname(" ");
System.out.println("");
System.out.println("============= ===========");
//
// “ , ” ,
IUser proxy = new StaticProxy("firs","123");
proxy.login("firs", "123");
proxy.editNickname(" ");
System.out.println("");
System.out.println("============= ===========");
DynamicProxy dynamicProxy = new DynamicProxy("firs","123",Admin.class);
ClassLoader cl = Admin.class.getClassLoader();
IUser iuser = (IUser)Proxy.newProxyInstance(cl,
new Class[]{IUser.class}, dynamicProxy);
iuser.login("firs","123");
iuser.editNickname(" ");
}
}
需要により増加したAdmin類
public class Admin implements IUser {
private String nickname;
private String userId;
private String password;
public Admin(String userId,String password){
this.userId = userId;
this.password = password;
}
@Override
public void login(String userId, String password){
if(this.userId == userId && this.password == password){
System.out.println(" ");
}
else
System.out.println(" ");
}
@Override
public void editNickname(String nickname) {
this.nickname = nickname;
System.out.println(" , :"+this.nickname);
}
}
まとめ:1.静的エージェントモードは比較的簡単であり、各実装クラス(subject本体)に対して、aopの制御など、エンティティクラス(subject本体)の参照があるエージェントクラスを新規に作成することができる。
2.静的エージェントには限界があり、各エンティティ類に対して静的エージェントを新規に作成する必要があり、このようにして静的エージェントが多すぎる場合があり、動的エージェントが生まれてきた。
3.動的エージェントは、具体的な実装クラス(subject本体)に限定されず、その内部では、Objectを用いてエンティティ類の参照にアクセスし、反射を利用してそのエンティティ類の様々な方法を獲得し、クラス(subject本体)を実現するための切断面AOPプログラミング制御を実現する。
4.上記の書き方はJDKのダイナミックエージェントであり、特に完璧ではない。このような動的エージェントはエンティティクラスが少なくとも一つのインターフェースを実現する必要があるからだ。問題はすべての種類にインターフェースがあるわけではないので、ここで完璧ではないです。
以上は私自身の代理モデルに対する理解です。もし間違いがあれば、ご指摘をお願いします。ありがとうございます。
以上のjavaデザインモード-プロキシモード(実例解説)は、小編集が皆さんに提供した内容の全部を共有しています。参考にしていただければと思います。どうぞよろしくお願いします。