主頁 > 軟體設計 > “無所不能的中介”——代理模式

“無所不能的中介”——代理模式

2023-03-01 08:38:56 軟體設計

1.簡介

定義:將某個物件中圍繞某個主題的一些列行為委托給一個代理物件去執行,代理物件將控制和管理對原有物件的訪問,呼叫者想要訪問目標物件,必須通過代理物件去間接訪問,代理物件在呼叫方和目標物件之間可以起到”中介“的作用,代理一詞本身,其實就可以很好發現的關鍵點,如果暫時無法理解晦澀的概念,那么在閱讀本文之前先通俗的理解:”就是找其他人代表你、協助你,去更好的幫你做事情“,

在現實生活中代理模式的場景其實無處不在,例如民用汽車消費場景就存在代理模式的影子,我們個人一般沒有權限直接從汽車生產商購買汽車的,并且需要專業人員為我們介紹汽車的引數,所以我們選擇從4S店作為購買汽車的途徑,那么在這個場景中,汽車4S店就屬于一個代理者,它代理了消費者從汽車生產商購買汽車的行為,不但提供給消費者便捷的購車渠道,還可以享受到售前的專業講解和售后維修保養服務,這些都是無法直接從汽車生產商獲得的,


2.應用場景介紹

在實際的開發場景中,我經常會遇到一種場景,簡單來說就是對現有的函式增加一些通用處理,例如,在訪問函式之前進行身份驗證、在資料操作之后進行日志記錄等,簡單粗暴的方式,就是將身份驗證和日志記錄的代碼直接添加在相應函式代碼最前面和代碼最后面,雖然這種方式解決了功能問題,但是在設計上存在一些弊端,

如果實作身份驗證或日志記錄的代碼邏輯存在隱患或產生變動,并且涉及使用的函式很多,那么這個改動量是比較大的,改動勢必會對系統產生風險,則需要為每個改動的方法及業務進行測驗作業(因為任何改動都會存在風險),這樣的場景反應了一個問題:函式中通用功能代碼和業務耦合在一起,通用功能的變化會引起這個函式的變化,以及不排除呼叫層對這個函式使用的變化,

為了減少函式中通用功能代碼和業務代碼之間的耦合性,這個時候我們就可以運用代理模式,簡單來說,我們在客戶端物件訪問原有業務函式之間增加一個代理物件,促使客戶端不能直接訪問業務函式,而只能通過代理物件間接訪問,

這樣一來,業務函式本身只專注于業務,與業務無關的擴展功能則轉交給代理物件,如果擴展功能發生變化,我們無需修改業務函式,而是修改代理物件,基于這種現象可以看出,代理模式很好的遵循了”開閉原則“,即類對擴展開放,對修改關閉,另外,代理物件除了提供給客戶端呼叫業務函式之外,還額外在業務函式執行之前和之后,提供身份驗證和日志記錄,


3.代理模式結構

3.1.Subject(抽象主題)

它是基于代理的“主題行為”抽象出的介面層,之所以稱為主題,是因為代理的行為會圍繞某個主題存在多個,比如資料庫操作這個主題,就存在“增刪改查”多個行為,

抽象主題是代理類和真實主題類都必須實作的介面,二者通過實作同一介面,代理類就可以在“真實主題類”使用的地方取代它,在呼叫層,客戶端物件就可以使用多型的形式,面向抽象主題介面編程,而抽象主題介面型別中實際的參考則是代理物件,代理物件中又包含了對“真實主題”物件的參考,從而促使呼叫層對“真實主題”物件的間接使用,

 3.2.Proxy(代理類)

代理類很好理解,相當于“中介”,主要作用是控制物件的訪問,代理類中處理實作抽象主題以外,還需要包含對被代理物件的參考,之所以要參考被代理物件,那是因為代理行為具體的實作任然是被代理者提供的,代理類只是類似于擴展的性質,在代理行為的執行之前或之后,結合應用場景欄位外的附加操作,如權限控制、日志等,所以代理的行為還是建立在“被代理者”提供的行為基礎之上,

 3.3.RealSubject(真實主題)

真實主題是真正做事的物件,它的訪問將由代理類進行控制,俗稱“被代理者”,抽象主題的定義往往就是根據“真實主題”的行為作為切入點抽象出來的,“真實主題”會承擔代理行為的具體實作邏輯,代理類中會參考“真實主題”物件對其進行呼叫,而在呼叫層不允許之間訪問該物件,而是通過代理物件間接的訪問它,


4.應用示例

接下來我們基于上文中的應用場景,以系統中常用的一個“用戶服務類”中的查詢方法作為我們實作代理模式的示例,我們將使用代理模式達到對“用戶服務類”的訪問控制,然后在代理類中在呼叫查詢方法的基礎上,在額外的增加身份驗證和日志記錄功能,該示例的代理模式結構如下:

 

在上面的類圖中,我們基于“用戶服務”中的行為作為主題抽象成了一個介面,介面中包含了我們需要代理的某個行為,即獲取用戶資訊,為了在編碼上代理類可以代替“用戶服務類”,故將它們都實作了“用戶服務介面”,這樣一來客戶端可以面向抽象編碼,將“代理類”和“用戶服務類”一致性看待,代理類中新增了Validate方法和Log方法,它們分別用于在“獲取用戶資訊”方法的基礎上,額外進行身份驗證和日志記錄,代理類中還參考了“用戶服務類”物件,它會重寫“GetUserList”方法,并在重寫方法中呼叫“用戶服務類”提供的“GetUserList”方法,然后再進行額外的功能附加,代碼示例如下:

 1      /// <summary>
 2     /// 用戶服務介面,代理模式中的“抽象主題類”
 3     /// </summary>
 4     public interface IUserService
 5     {
 6         List<string> GetUserList();
 7     }
 8 
 9 
10      /// <summary>
11     /// 用戶服務類,代理模式中的“真實主題類”
12     /// </summary>
13     public class UserService : IUserService
14     {
15         public List<string> GetUserList()
16         {
17             Console.WriteLine("正在連接資料庫,查詢所有用戶資訊,,,");
18 
19             List<string> userList = new List<string> 
20             { 
21                 "蘇軾","李白","辛棄疾","岳飛","白居易"
22             };
23 
24             return userList;
25         }  // END GetUserList()
26 
27     }
28 
29   /// <summary>
30     /// 用戶服務代理類,代理模式中的“代理類”
31     /// </summary>
32     public class ProxyUserService : IUserService
33     {
34         private IUserService _userService = new UserService();
35 
36         public List<string> GetUserList()
37         {
38             if (Validate()) //身份驗證
39             {
40                 List<string> userList = _userService.GetUserList(); //呼叫真實主題物件的查詢方法
41                 Log();//日志記錄
42                 return userList;
43             }
44 
45             return null;
46         } // END GetUserList()
47 
48         public bool Validate()
49         {
50             //偽代碼,模擬獲取用戶資訊
51             string currentUserId = "張三";
52 
53             if (currentUserId== "張三")
54             {
55                 Console.WriteLine($"“{currentUserId}”用戶的權限認證成功!");
56                 return true;
57             }
58             else
59             {
60                 Console.WriteLine($"“{currentUserId}”用戶的權限認證失敗!");
61                 return false;
62             }
63 
64         } // END Validate()
65 
66         public void Log()
67         {
68             //偽代碼,模擬獲取用戶資訊
69             string currentUserId = "張三";
70 
71             Console.WriteLine($"用戶:“{currentUserId}與{DateTime.Now}查詢了用戶資訊,”");
72 
73         }// END Log()
74 
75     }

客戶端呼叫代碼:

 1 //創建代理物件
 2 IUserService proxyUserService = new ProxyUserService();
 3 
 4 //使用代理物件獲取用戶資訊
 5 List<string> userList= proxyUserService.GetUserList();
 6 
 7 //輸出
 8 Console.WriteLine("\r\n輸出用戶資訊:");
 9 foreach (var user in userList)
10 {
11     Console.WriteLine(user);
12 }

輸出結果:

 


5.動態代理

5.1.靜態代理的不足

代理模式中通過“代理物件”實作了對“目標物件”的控制,從而可以在“目標物件”原有的方法基礎上進行額外的擴展,并且這種擴展方式是可以在不修改原有目標物件代碼的基礎上實作,促使原有目標物件實作了開閉原則,

盡管如此,目前的代理模式仍有美中不足,由于我們代理類以及代理的行為都是預先定義好的,如果抽象主題中需要新增方法,也就是某個代理類要新增代理行為,那么代理類則必須要做出相應的實作,并且在實作的方法中,對于通用處理的功能,會在不同的方法中出現冗余,

例如本實體中的“用戶服務類”,在實際的專案中類似這種資料服務類,肯定不僅只有“查詢用戶”一種方法,必然會有“增刪改查”一系列的方法,如果要為其增加“增刪改”方法,那么代理類想要代理這些行為,則必須在重寫“抽象主題介面”的方法,并且對于通用附加功能(權限、日志等)的代碼會產生很多冗余,

 

除此之外,實際專案中如果存在大量的代理需求,那么我們可能會為不同型別、不同業務領域的服務類撰寫大量的代理類,在撰寫大量代理類后,你會發現代理類的結構都幾乎相同,都只是在代理行為的之前或之后做一些處理,那么這樣也會產生許多重復,基于這種背景下,為了尋找一種通用化的代理方案,就衍生出了一種動態代理模式,而以上我們示例中應用的模式反之為靜態代理,

對于靜態代理而言,代理類都是預先撰寫定義好的,這導致隨著代理需求的增加還需要新增相應的代理類,并且代理行為增加,代理類也需要不斷去實作相應的方法,“唯一不變的是變化本身”,我們不可能預知系統的所有代理需求,不可能預估系統中,哪些類、哪些方法需要被代理,

為了應對這種變化,我們可以使用動態代理,它相當于定義了一個通用化的代理模板,我們不需要預先定義代理類,它會根據你在客戶端使用的“抽象主題型別”動態創建代理物件,只要你使用的目標物件使用了代理模式,這個通用的代理模板都會為目標物件動態的生成代理類,并且我們不需要在代理類中去實作代理行為,它會有一種通用的呼叫方式,將代理擴展的行為作用于每個方法,

 5.2.DispatchProxy

下面我們將使用System.Reflection命名空間下的DispatchProxy型別來實作動態代理,該型別只適用于.NET框架4.6以上版本和.NET Core,對于較低版本的.NET框架不支持,

我們將延用靜態代理中的“抽象主題”和“真實主題”,在此基礎之上撰寫動態代理類,該代理類主要代理系統中服務類的“增刪改查”行為,并在各個服務類的“增刪改查”方法之前和之后加上身份驗證和日志記錄,具體代碼如下:

 1.創建動態代理型別

 1     /// <summary>
 2     /// 動態代理類
 3     /// </summary>
 4     /// <typeparam name="T">抽象主題型別</typeparam>
 5     public class ProxyCRUD<T> : DispatchProxy 
 6     {
 7         //目標物件,被代理物件
 8         public T Target { get; private set; }
 9 
10         /// <summary>
11         /// 創建“動態代理類”物件,并指定一個“被代理物件”
12         /// </summary>
13         /// <param name="target">被代理物件</param>
14         /// <returns>抽象主題型別(代理介面),但型別的參考指向的是“動態代理物件”</returns>
15         public static T Decorate(T target)
16         {
17             //創建一個實作“抽象主題介面”的“動態代理物件”
18             dynamic proxy = Create<T, ProxyCRUD<T>>();
19 
20             //指定“動態代理物件”代理的目標物件,即被代理的物件
21             proxy.Target = target;
22 
23             return proxy;
24         }
25         // END Decorate()
26 
27         /// <summary>
28         /// 動態代理物件執行代理行為
29         /// “被代理物件”的方法被代理物件執行時,會通過該方法間接呼叫
30         /// </summary>
31         /// <param name="targetMethod">“被代理物件”的方法資訊</param>
32         /// <param name="args">方法的引數</param>
33         /// <returns>方法執行的回傳值</returns>
34         protected override object? Invoke(MethodInfo? targetMethod, object?[]? args)
35         {
36             if (Validate()) //擴展通用處理:身份驗證
37             {
38                 //通過反射的方式呼叫“被代理物件”的原始方法
39                 var result = targetMethod.Invoke(Target,args);
40 
41                 Log(targetMethod.Name);//擴展通用處理:日志記錄
42 
43                 return result;
44             }
45             else
46             {
47                 return null;
48             }
49 
50         }// END Invoke ()
51 
52         /// <summary>
53         /// 身份驗證(偽代碼)
54         /// </summary>
55         public bool Validate()
56         {
57             //偽代碼,模擬獲取用戶資訊
58             string currentUserId = "張三";
59 
60             if (currentUserId == "張三")
61             {
62                 Console.WriteLine($"“{currentUserId}”用戶的權限認證成功!");
63                 return true;
64             }
65             else
66             {
67                 Console.WriteLine($"“{currentUserId}”用戶的權限認證失敗!");
68                 return false;
69             }
70 
71         } // END Validate()
72 
73         /// <summary>
74         /// 日志記錄(偽代碼)
75         /// </summary>
76         public void Log(string action)
77         {
78             //偽代碼,模擬獲取用戶資訊
79             string currentUserId = "張三";
80 
81             Console.WriteLine($"用戶:{currentUserId}在{DateTime.Now}執行了{action}操作,");
82 
83         }// END Log()
84 
85     }

以上代碼中的“動態代理類”是一個泛型類,其中泛型的型別引數,需要指定代理模式中的“抽象主題型別”,也就是被代理類和代理類都需要實作的介面型別,在靜態模式中,“抽象主題型別”是指定的一個具體型別,而這里使用了泛型的型別引數,這就意味該類可以適用于所有型別的代理,就像List<T>一樣,不光可以用于List<int>集合、還可以用于List<string>、List<object>等,

其中派生自“DispatchProxy”類,實作的Invoke方法是代理行為的核心,在呼叫層通過代理物件呼叫任何方法時,都會將方法的執行帶入到Invoke方法中,換句話說,我們使用動態代理物件去執行方法時,就像通過“傳送門”就方法的執行轉發到Invoke方法中,然后在該方法中可以在原始方法的基礎上額外擴展其他功能,

 2.客戶端呼叫

 1 //創建真實主題物件,即被代理物件
 2 UserService userService = new UserService();
 3 
 4 /*【創建代理物件】
 5  * 根據“抽象主題介面”動態創建代理物件,并實作“抽象主題介面”
 6  * “被代理物件”作為引數指定給了“代理物件”
 7  */
 8 var proxyUserService = ProxyCRUD<IUserService>.Decorate(userService);
 9 
10 /*
11  * 方法源于“抽象主題”,實作源于“被代理物件”,
12  * “代理物件”代理了方法的呼叫,
13  */
14 var userList = proxyUserService.GetUserList();
15 
16 Console.WriteLine("\r\n輸出用戶資訊:");
17 foreach (var user in userList)
18 {
19     Console.WriteLine(user);
20 }

6.代理和裝飾

代理模式和裝飾模式在實作時有些類似,但是代理模式主要是給“真實主題類”增加一些全新的職責,例如在業務方法執行之前進行權限驗證、例如在業務方法執行之后附加日志記錄等,這些職責往往是非業務的,與業務職責不屬于同一個問題域,

對于裝飾模式而言,它是通過裝飾類為具體構建類增加一些與業務職責相關的職責,是對原有業務職責的擴展,擴展的職責和原有業務都屬于同一個問題域,代理模式和裝飾模式的目的也不相同,代理模式達到控制物件的訪問,而裝飾模式是為物件動態地增加功能,可以看作是填補繼承不靈活性的另一種功能復用方案,


7.總結

代理模式的結構是比較簡單的,實際上就是將某個型別的“代理需求”(類的行為/方法/業務)建立一個“抽象主題”(介面)并提供方法的實作,然后我們面向這個“抽象主題”創建一個代理類,并在代理類中參考“被代理物件”,然后在“被代理物件”的“行為/方法/業務”執行的基礎上進行額外的加工、管控,

代理模式的應用場景非常廣泛,難點就在如何應用到不同場景,并且不同場景還涉及到其他領域的特有技術,其中常用的應用場景包括:遠程代理、虛擬代理、保護代理、智能參考代理,以及AOP的實作,本文中的示例是針對“智能參考代理”場景的應用,也就是在目標物件原有的業務方法之上,為物件提供一些額外的通用處理,

本文屬于代理模式的基礎教程,所以在此不能詳細闡述所有的應用場景,下面根據較常用的場景進行簡單概要:

  1. 遠程代理:當你的主機想要訪問遠程主機中的物件時,可以使用遠程代理幫你建立一個網路橋梁,它會幫你訪問網路轉發請求來完成遠程物件的呼叫,
  2. 虛擬代理:當加載的物件資源大、耗時長,可以使用虛擬代理為這種物件建立一個輕量級的替身物件先預載,從而降低系統開銷、縮短運行時間時,
  3. 保護代理:當需要控制對一個物件的訪問,為不同用戶提供不同級別的訪問權限時,可以使用保護代理
  4. 智能參考代理:當訪問某個物件的行為需要做一些額外的擴展操作時,可以使用智能參考代理,

 

知識改變命運

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/545369.html

標籤:其他

上一篇:“無所不能的中介”——代理模式

下一篇:如何畫好一張架構圖?(內含知識圖譜)

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more