主頁 > 軟體設計 > 行為型設計模式(上)

行為型設計模式(上)

2020-09-15 04:26:20 軟體設計

責任鏈模式:

 

下圖為責任鏈

  1、定義:為了避免請求發送者與多個請求處理者耦合在一起,將所有請求的處理者通過前一物件

        記住其下一個物件的參考而連成一條鏈當有請求發生時,可將請求沿著這條鏈傳遞,直到有物件處理它為止

  2、模型結構:

    (1)抽象處理者(Handler):定義一個處理請求的介面,包含抽象處理方法一個后繼連接

    (2)具體處理者(Concrete Handler):實作抽象處理者的處理方法,判斷能否處理本次請求,

                          如果可以處理請求則處理,否則將該請求轉給它的后繼者

  3、優點:

    (1)降低了物件之間的耦合度,該模式使得一個物件無須知道到底是哪一個物件處理其請求以及鏈的結構,

      發送者和接收者也無須擁有對方的明確資訊

    (2)增強了系統的可擴展性,可以根據需要增加新的請求處理類,滿足“開閉原則”

    (3)增強了給物件指派職責的靈活性,當作業流程發生變化,可以動態地改變鏈內的成員或者調動它們的次序,

      也可動態地新增或者洗掉責任

    (4)簡化了物件之間的連接,每個物件只需保持一個指向其后繼者的參考,

      不需保持其他所有處理者的參考,這避免了使用眾多的分支陳述句

    (5)責任分擔,每個類只需要處理自己該處理的作業,不該處理的傳遞給下一個物件完成,

      明確各類的責任范圍,符合類的單一職責原則

注:單一職責原則規定一個類應該有且僅有一個引起它變化的原因,否則類應該被拆分

  4、缺點:

    (1)不能保證每個請求一定被處理,由于一個請求沒有明確的接收者,

      所以不能保證它一定會被處理,該請求可能一直傳到鏈的末端都得不到處理

    (2)對比較長的職責鏈,請求的處理可能涉及多個處理物件,系統性能將受到一定影響

    (3)職責鏈建立的合理性要靠客戶端來保證,增加了客戶端的復雜性

      可能會由于職責鏈的錯誤設定而導致系統出錯,如可能會造成回圈呼叫

  5、適用環境:

    (1)有多個物件可以處理一個請求,哪個物件處理該請求由運行時刻自動確定

    (2)可動態指定一組物件處理請求,或添加新的處理者

    (3)在不明確指定請求處理者的情況下,向多個處理者中的一個提交請求

// 抽象處理者 Handlerabstract class ATeacher {    // 鏈式結構,需要包含一個指向下一個 Handler 的物件    protected aTeacher: ATeacher;    setTeacher(teacher: ATeacher): void {        this.aTeacher = teacher;    }    getTeacher(): ATeacher {        return this.aTeacher;    }    abstract handler(level: number): void;}// 具體處理者 Concrete Handlerclass Teacher extends ATeacher {    private name: string;    private something: string;    constructor(name: string, something: string) {        super();    // Constructors for derived classes must contain a 'super' call        this.name = name;        this.something = something    }    handler(level: number): void {        if (level >= 3) {            console.log("授課老師同意...");        } else {            console.log("授課老師無權受理...");            this.getTeacher().handler(level);        }    }}class Moniteur extends ATeacher {    private name: string;    private something: string;    constructor(name: string, something: string) {        super();    // Constructors for derived classes must contain a 'super' call        this.name = name;        this.something = something    }    handler(level: number): void {        let flag: boolean = true;   // 設定為同意        if (level >= 2) {            if (flag)                console.log("輔導員同意...");            else                console.log("輔導員不同意...");        } else {            console.log("輔導員無權受理...");            this.getTeacher().handler(level);        }    }}class Directeur extends ATeacher {    private name: string;    private something: string;    constructor(name: string, something: string) {        super();    // Constructors for derived classes must contain a 'super' call        this.name = name;        this.something = something    }    handler(level: number): void {        let flag: boolean = false;  // 設定為不同意        if (level >= 1) {            if (flag)                console.log("主任同意...");            else                console.log("主任不同意...");        } else {            console.log("主任無權受理...");            this.getTeacher().handler(level);        }    }}let stuName1: string = "Lemon";let thing: string = "Go home";let teacher1: ATeacher = new Teacher(stuName1, thing);let teacher2: ATeacher = new Moniteur(stuName1, thing);let teacher3: ATeacher = new Directeur(stuName1, thing);teacher1.setTeacher(teacher2);teacher2.setTeacher(teacher3);// 授課老師無權受理...// 輔導員同意...teacher1.handler(2);

 

命令模式:

  1、定義:將一個請求封裝為一個物件,使發出請求的責任和執行請求的責任分割開,

        這樣兩者之間通過命令物件進行溝通,這樣方便將命令物件進行儲存、傳遞、呼叫、增加與管理

  2、模型結構:

    (1)抽象命令類(Command):宣告執行命令的介面,擁有執行命令的抽象方法

    (2)具體命令類(ConcreteCommand):是抽象命令類的具體實作類,它擁有接收者物件

                         并通過呼叫接收者的功能來完成命令要執行的操作

    (3)呼叫者(Invoker):請求的發送者,它通常擁有很多的命令物件,

                 并通過訪問命令物件來執行相關請求,不直接訪問接收者

    (4)接收者(Receiver):執行命令功能的相關操作,是具體命令物件業務的真正實作者

  3、優點:

    (1)降低系統的耦合度:命令模式能將呼叫操作的物件與實作該操作的物件解耦

    (2)增加或洗掉命令非常方便:采用命令模式增加與洗掉命令不會影響其他類,滿足“開閉原則”,擴展比較靈活

    (3)可以實作宏命令:命令模式可以與組合模式結合,將多個命令裝配成一個組合命令,即宏命令

    (4)方便實作 Undo 和 Redo 操作:命令模式可以與后面介紹的備忘錄模式結合,實作命令的撤銷與恢復

  4、缺點:可能產生大量具體命令類,因為計對每一個具體操作都需要設計一個具體命令類,這將增加系統的復雜性

  5、適用環境:

    (1)系統需要將請求呼叫者和請求接收者解耦,使得呼叫者和接收者不直接互動

    (2)系統需要在不同的時間指定請求、將請求排隊和執行請求

    (3)系統需要支持命令的撤銷(Undo)操作和恢復(Redo)操作

    (4)系統需要將一組操作組合在一起,即支持宏命令

// 接收者 Receiverclass RStudent {    clean(name: string): void {        console.log(name + " begin cleaning...");    }    doHomwork(name: string) {        console.log(name + " begin doing homework...");    }}// 抽象命令類 Commandabstract class Command {    protected student: RStudent;    constructor(student: RStudent) {        this.student = student;    }    abstract execute(name: string): void;}// 具體命令類 ConcreteCommandclass LiTeacher extends Command {    constructor(student: RStudent) {        super(student);    }    execute(name: string): void {        this.student.clean(name);    }}class WangTeacher extends Command {    constructor(student: RStudent) {        super(student);    }    execute(name: string): void {        this.student.doHomwork(name);    }}// 呼叫者 Invokerclass Invoker {    protected command: Command;    commands: Command[] = new Array<Command>();    executeCommand(name:  string): void {        this.command = this.commands.shift();        this.command.execute(name);        console.log("Executing one command...");    }    setCommand(command: Command): void {        console.log(`Here are ${this.commands.length} things must be executed before execute this`);        this.commands.push(command);    }    undoCommand(): void {        if (this.commands.length) {            this.commands.pop();            console.log("Undo command is successful!");        } else {            console.log("You shouldn't execute any command after you set it if you want to undo it...");        }    }}let stuName: string = "Tim";let stu: RStudent = new RStudent();let command1: LiTeacher = new LiTeacher(stu);let command2: WangTeacher = new WangTeacher(stu);let invoker: Invoker = new Invoker();invoker.setCommand(command1);   // Here are 0 things must be executed before execute thisinvoker.setCommand(command2);   // Here are 1 things must be executed before execute thisinvoker.executeCommand(stuName);    // Tim begin cleaning...  \n  Executing one command...invoker.setCommand(command1);   // Here are 1 things must be executed before execute thisinvoker.undoCommand();  // Undo command is successful!invoker.executeCommand(stuName);    // Tim begin doing homework...  \n  Executing one command...

 

解釋器模式:

  1、定義:給分析物件定義一個語言,并定義該語言的文法表示,再設計一個決議器來解釋語言中的句子

注:文法是用于描述語言的語法結構的形式規則

  2、模型結構:

    (1)抽象運算式(Abstract Expression):定義解釋器的介面,約定解釋器的解釋操作

    (2)終結符運算式(Terminal Expression):抽象運算式的子類,用來實作文法中與終結符相關的操作,

                             文法中的每一個終結符都有一個具體終結運算式與之相對應

    (3)非終結符運算式(Nonterminal Expression):抽象運算式的子類,用來實作文法中與非終結符相關的操作,

                                文法中的每條規則都對應于一個非終結符運算式

    (4)環境(Context):通常包含各個解釋器需要的資料或是公共的功能,一般用來傳遞被所有解釋器共享的資料

                后面的解釋器可以從這里獲取這些值

  3、優點:

    (1)擴展性好:由于在解釋器模式中使用類來表示語言的文法規則,因此可以通過繼承等機制來改變或擴展文法

    (2)容易實作:在語法樹中的每個運算式節點類都是相似的,所以實作其文法較為容易

注:語法樹是句子結構的一種樹型表示,它代表了句子的推導結果,它有利于理解句子語法結構的層次

  4、缺點:

    (1)執行效率較低:解釋器模式中通常使用大量的回圈和遞回呼叫,當要解釋的句子較復雜時,

               其運行速度很慢,且代碼的除錯程序也比較麻煩

    (2)引起類膨脹:解釋器模式中的每條規則至少需要定義一個類,當包含的文法規則很多時,

              類的個數將急劇增加,導致系統難以管理與維護

    (3)可應用的場景比較少:在軟體開發中,需要定義語言文法的應用實體非常少,所以這種模式很少被使用到

  5、適用環境:

    (1)當語言的文法較為簡單,且執行效率不是關鍵問題時

    (2)當問題重復出現,且可以用一種簡單的語言來進行表達時

    (3)當一個語言需要解釋執行,并且語言中的句子可以表示為一個抽象語法樹的時候,如 XML 檔案解釋

// 抽象運算式interface AbstractExpression {    interpret(age: string, occupation: string): boolean;}// 終結符運算式class TerminalExpression implements AbstractExpression {    private set: Set<string> = new Set<string>();    constructor(data: string[]) {        for (let i in data) {            this.set.add(data[i]);        }    }    interpret(age: string, occupation: string): boolean {        if (Number(age) <= 12 || this.set.has(occupation)) {            return true;        }        return false;    }}// 非終結符運算式class AndExpression implements AbstractExpression {    private people: AbstractExpression = null;    constructor(people: AbstractExpression) {        this.people = people;    }    interpret(age: string, occupation: string): boolean {        return this.people.interpret(age, occupation);    }}// 環境類class Context {    private occupations: string[] = ["學生", "老人", "孕婦"];    private people: AbstractExpression;    constructor() {        let occupation: AbstractExpression = new TerminalExpression(this.occupations);        this.people = new AndExpression(occupation);    }    halfPrice(info: string) {        let info_arr: string[] = info.split("歲");        let ok: boolean = this.people.interpret(info_arr[0], info_arr[1]);        if (ok) {            console.log(`您是${info},本次費用半價...`);        } else {            console.log(`${info},您不是優惠人群,本次費用全票...`);        }    }}let sp: Context = new Context();sp.halfPrice("12歲學生");   // 您是12歲學生,本次費用半價...sp.halfPrice("8歲兒童");    // 您是8歲兒童,本次費用半價...sp.halfPrice("20歲學生");   // 您是20歲學生,本次費用半價...sp.halfPrice("68歲老人");   // 您是68歲老人,本次費用半價...sp.halfPrice("28歲孕婦");   // 您是28歲孕婦,本次費用半價...sp.halfPrice("18歲無業游民");   // 18歲無業游民,您不是優惠人群,本次費用全票...

 

迭代器模式:

  1、定義:提供一個物件來順序訪問聚合物件中的一系列資料,而不暴露聚合物件的內部表示

  2、模型結構:

    (1)抽象聚合(Aggregate):定義存盤、添加、洗掉聚合物件以及創建迭代器物件的介面

    (2)具體聚合(ConcreteAggregate):實作抽象聚合類,回傳一個具體迭代器的實體

    (3)抽象迭代器Iterator:定義訪問和遍歷聚合元素的介面,通常包含 hasNext()、first()、next() 等方法

    (4)具體迭代器(Concretelterator):實作抽象迭代器介面中所定義的方法,完成對聚合物件的遍歷,

                          記錄遍歷的當前位置

  3、優點:

    (1)訪問一個聚合物件的內容而無須暴露它的內部表示

    (2)遍歷任務交由迭代器完成,這簡化了聚合類

    (3)它支持以不同方式遍歷一個聚合,甚至可以自定義迭代器的子類以支持新的遍歷

    (4)增加新的聚合類和迭代器類都很方便,無須修改原有代碼

    (5)封裝性良好,為遍歷不同的聚合結構提供一個統一的介面

  4、缺點:增加了類的個數,這在一定程度上增加了系統的復雜性

  5、適用環境:

    (1)當需要為聚合物件提供多種遍歷方式

    (2)當需要為遍歷不同的聚合結構提供一個統一的介面

    (3)當訪問一個聚合物件的內容而無須暴露其內部細節的表示時

// 學校類,用于聚合class School {    private schoolName: string;    constructor(schoolName: string) {        this.schoolName = schoolName;    }    printName(): void {        console.log(this.schoolName);    }}// 抽象聚合interface Aggregate {    add(school: School): void;    remove(): School;    getIterator(): MyIterator;}// 具體聚合class ConcreteAggregate implements Aggregate {    private schoolList: School[] = new Array<School>();    add(school: School): void {        this.schoolList.push(school);    }    remove(): School {        let temp: School = this.schoolList.pop();        return temp;    }    getIterator(): MyIterator {        return new ConcreteIterator(this.schoolList);    }}// 抽象迭代器interface MyIterator {    first(): School;    next(): School;    hasNext(): boolean;    reset(): void;}// 具體迭代器class ConcreteIterator implements MyIterator {    private schoolList: School[];    private index: number = -1;    constructor(schoolList: School[]) {        this.schoolList = schoolList;    }    first(): School {        let first: School = null;        if (this.schoolList.length > 0)            first = this.schoolList[0];        return first;    }    next(): School {        let next: School = null;        if (this.hasNext())            // index 初始值為 -1,所以需要先加            next = this.schoolList[++this.index];        return next;    }    hasNext(): boolean {        if (this.index < this.schoolList.length-1)            return true;        return false;    }    reset(): void {        this.index = -1;    }}let school1: School = new School("華南師范大學");let school2: School = new School("北京郵電大學");let school3: School = new School("東南大學");let schools: Aggregate = new ConcreteAggregate();schools.add(school1);schools.add(school2);schools.add(school3);let it: MyIterator = schools.getIterator();while (it.hasNext()) {    it.next().printName();  // 依次輸出學校名字}it.first().printName(); // 華南師范大學console.log(it.hasNext());  // false,因為 index 已經到末尾了it.reset(); // 重置 indexconsole.log(it.hasNext());  // trueschools.remove().printName();   // 東南大學

 

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/42127.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