国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - java設計模式-代理模式(實例講解)

java設計模式-代理模式(實例講解)

2021-01-12 13:56firs大風吹 Java教程

下面小編就為大家帶來一篇java設計模式-代理模式(實例講解)。小編覺得挺不錯的,現在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

代理模式java最常見的設計模式之一。spring的aop就是使用了代理模式。

一般而言,代理模式分為靜態代理和動態代理兩種。

作為結構類的設計模式,作用在于不修改類內部代碼的情況下,對類進行拓展,是對繼承機制的一種補充。

eg :下面就用戶登錄這個例子實現一下代理模式。

基本需求是:實現用戶的登錄和修改昵稱功能。

上代碼,先是IUser接口和user實現類

?
1
2
3
4
5
6
7
public interface IUser {
 //登錄
 void login(String userId,String password);
 //修改昵稱
 void editNickname(String nickname);
 
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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);
 }
 
}

客戶端類

?
1
2
3
4
5
6
7
public class Client {
 public static void main(String[] args) {
  //不調用代理模式時
  IUser user = new User("firs","123");
  user.login("firs", "123");
  user.editNickname("大風");
}

還是非常簡單的??墒呛竺娈a品經理跟你說,我們需要增加一個記錄用戶行為的功能,這下該怎么辦呢?直接修改user類?不不不,用代理模式。

增加一個代理類,在代理類里面寫“記錄用戶行為”的功能就好,不修改類,只拓展類,減少錯誤發生。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
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);
 }
 
}

客戶端類:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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("我還是大風");
 
}

這樣子只需要修改客戶端類和增加靜態代理就可以了,完美實現。可是需求是無窮無盡的,產品經理跟你說:“我們增加了一個管理員角色,還有二級管理員”啥啥啥的一大堆角色,

這就尷尬了,每個角色都要建一個靜態代理類,類爆炸了吧。不急,我們有動態代理模式。

動態代理模式在于不用自己新建代理類,你傳具體的實現類(主體)給他,他就默認給你生成了一個代理類。

從本質上來說,它是利用了java的反射機制在運行時動態地生成了相應的代理類。

沒有反射,就沒有動態代理。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
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);
 }
 
}

最后的客戶端類:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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類

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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主體)新建一個代理類,該代理類內有實體類(subject主體)的引用,從而可以實現對原有實現類(subject主體)的控制,包括aop的控制等。

2.靜態代理是有局限性的,對于每個實體類可能都需要新建一個靜態代理類,這樣子可能會造成靜態代理類過多的情況,所以動態代理應運而生了。

3.動態代理不局限于具體的實現類(subject主體),在其內部是用object存取實體類的引用,再利用反射獲得該實體類的各種方法,從而實現對實現類(subject主體)的面向 切面AOP編程控制。

4.上述的寫法是JDK里的動態代理,不是特別完美,因為這種動態代理需要實體類實現至少一個接口。問題是并不是所有的類都會有接口,所以說不完美在這里。

上面都是我自己對于代理模式的理解,如有錯漏,還請批評指正,多謝。

以上這篇java設計模式-代理模式(實例講解)就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持服務器之家。

原文鏈接:http://www.cnblogs.com/sundaymorning/archive/2017/09/27/7579540.html

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 日韩在线二区 | 欧美日韩亚洲二区 | 丁香综合| 午夜国产视频 | 久久在线视频 | 亚洲欧美视屏 | 久久久免费少妇高潮毛片 | www.色.com| 亚洲精品国产综合区久久久久久久 | 午夜免费剧场 | 一区二区三区国产视频 | 日韩成人在线观看 | 国产精品亚洲视频 | 国产在线观看一区二区三区 | 欧美日韩一级视频 | 99久久婷婷国产精品综合 | 亚洲另类视频 | 黄色永久网站 | 天天操天天操 | 欧美 亚洲 另类 激情 另类 | 亚洲精品欧美在线 | 伊人网视频 | 中文一区 | 国产精品自在线 | 精品综合久久久 | 亚洲热综合 | 精品久久久久久国产 | 欧美精品在线一区二区三区 | 杨门女将寡妇一级裸片看 | 91精品一区二区三区久久久久久 | 99精品久久久久久久免费 | 国产一区二区亚洲 | 波多野结衣中文字幕一区二区三区 | 四虎影视 | 日韩精品日韩激情日韩综合 | 91亚洲精品在线观看 | 91av在线免费播放 | 精品久久国产字幕高潮 | 黄片毛片毛片毛片 | 亚洲国产成人精品久久 | 欧美a级片在线观看 |