原型模式 (Prototype Pattern)

定義:

原型模式(Prototype Pattern)是一種創建型設計模式,它用于創建重復的對象,同時保持性能。這種模式的核心思想是通過復制一個已存在的實例來創建新的實例,而不是新建實例并對其進行初始化。原型模式適用于創建復雜對象的情況,特別是當對象創建的成本比較高時,如需要進行繁瑣的資源消耗型操作(例如,數據庫或文件的讀取操作)。

原型模式通常涉及以下幾個角色:

  1. 原型(Prototype)
    • 定義用于復制現有對象以生成新對象的接口。
  2. 具體原型(Concrete Prototype)
    • 實現原型接口的類,并提供復制自身的方法。這通常通過實現一個克隆方法(如Java中的 clone() 方法)來完成。
  3. 客戶(Client)
    • 創建新的對象時,客戶端使用原型實例提供的克隆方法來獲取新對象的副本,而不是直接通過new關鍵字創建。
解決的問題:
  • 高成本的對象創建
    • 當創建一個對象的成本很高時,因為它需要進行復雜的初始化,如從數據庫讀取數據或進行復雜的計算。原型模式通過復制現有對象來避免這種高成本的創建過程。
  • 避免復雜的構造過程
    • 在某些情況下,對象的創建過程可能涉及多個步驟和要求,使用原型模式可以通過直接復制一個已經創建好的實例來簡化創建過程。
  • 動態添加或刪除對象
    • 在運行時動態地添加或刪除具有特定配置的對象時,原型模式提供了一種方便的方法來復制配置相同的實例。
  • 對象的解耦
    • 有時,系統需要獨立于其要創建對象的類。原型模式允許你復制一個對象,而不需要依賴于它們的具體類。
  • 優化性能和內存
    • 使用原型模式可以減少系統的整體資源消耗,因為復制通常比創建全新實例更輕量級。
使用場景:
  • 性能敏感的對象創建
    • 當對象的創建過程涉及昂貴的數據庫操作、文件讀取、復雜計算或網絡調用等,而復制現有對象的成本相對較低時。
  • 避免復雜的初始化步驟
    • 如果一個對象的初始化過程非常復雜,如設置多個字段和依賴,使用原型模式可以通過克隆一個已經初始化的實例來避免這些復雜性。
  • 類不容易獲取或無法預知
    • 當需要實例化的類在運行時才確定,或者類的實例化過程隱藏在一些我們無法訪問的API后面時。
  • 動態加載或生成對象
    • 在需要根據當前環境或狀態動態生成對象的場景中,可以通過復制預先存儲的原型來實現。
  • 大量相似對象的場景
    • 當系統需要大量相似對象時,使用原型模式可以避免類初始化時的重復工作。
  • 實現對象的解耦
    • 當需要解耦系統中的對象創建和使用時,原型模式允許用戶無需知道對象的具體類型就能創建新實例。
示例代碼 1 - 淺拷貝實現:
public class ShallowPrototype implements Cloneable {private String name;public ShallowPrototype(String name) {this.name = name;}// getter和setter@Overridepublic ShallowPrototype clone() throws CloneNotSupportedException {return (ShallowPrototype) super.clone();}
}
示例代碼 2 - 深拷貝實現:
public class DeepPrototype implements Cloneable {private String name;private SomeComplexObject complexObject;public DeepPrototype(String name, SomeComplexObject complexObject) {this.name = name;this.complexObject = complexObject;}// getter和setter@Overridepublic DeepPrototype clone() throws CloneNotSupportedException {DeepPrototype cloned = (DeepPrototype) super.clone();cloned.complexObject = new SomeComplexObject(this.complexObject); // 創建新的復雜對象實例return cloned;}
}class SomeComplexObject {private String data;public SomeComplexObject(SomeComplexObject obj) {this.data = obj.data;}// getter和setter
}
主要符合的設計原則:
  1. 開閉原則(Open-Closed Principle):
    • 原型模式支持開閉原則。一旦原型對象被創建并實現了克隆(Clone)方法,你可以通過克隆現有對象來添加新的對象實例,而無需修改現有的代碼。
  2. 單一職責原則(Single Responsibility Principle):
    • 原型模式允許將對象創建和業務邏輯分離,使得每個類專注于單一的職責。原型對象專注于如何創建和復制自身的實例。
  3. 里氏替換原則(Liskov Substitution Principle):
    • 在原型模式中,任何繼承自原型的新對象都應當能替代原型對象。這符合里氏替換原則,即程序中的對象應該能夠被其子類對象所替換,而程序的邏輯不受影響。

原型模式主要通過實現開閉原則和單一職責原則來提高代碼的可維護性和可擴展性。通過克隆方法,它允許在運行時動態地創建對象,提供了創建對象的靈活方式,同時避免了復雜的構造過程。

在JDK中的應用:
  • java.lang.Objectclone() 方法
    • 在Java中,所有類都繼承自 java.lang.ObjectObject 類提供了一個 clone() 方法,可以用來復制對象。盡管這個方法默認是淺復制,但它提供了實現深復制的基礎。
  • Java集合框架
    • 許多Java集合類(如 ArrayList, HashSet, HashMap 等)實現了 Cloneable 接口,提供了 clone() 方法來創建集合的副本。這些集合類的克隆方法通常提供了集合內容的淺復制。
  • 日期和時間對象
    • 諸如 java.util.Date 這樣的日期和時間相關類也實現了 Cloneable 接口,允許通過克隆方法來創建日期對象的精確副本。
在Spring中的應用:
  • Bean的原型作用域
    • 在Spring框架中,Bean的作用域默認是單例(singleton),但可以配置為原型(prototype)。當一個Bean被定義為原型作用域時,每次通過容器請求這個Bean時,Spring容器都會創建一個新的Bean實例,而不是返回一個共享的單例實例。這正是原型模式的應用,即每次需要時都創建一個新的對象副本。
  • 解決單例Bean的狀態問題
    • 在某些情況下,如果單例Bean包含了可變的數據字段,那么在并發環境下可能會出現數據安全問題。通過將這樣的Bean定義為原型作用域,可以為每個請求創建一個新的實例,從而避免了狀態共享的問題。

雖然Spring中原型作用域的應用并不廣泛,但在需要獨立狀態或避免共享狀態的場景中,原型模式提供了一種有效的解決方案。需要注意的是,與單例Bean相比,原型Bean的生命周期管理、依賴注入和銷毀需要更多地由開發者來控制。


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/165008.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/165008.shtml
英文地址,請注明出處:http://en.pswp.cn/news/165008.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

jetson xavier NX深度學習環境配置

文章目錄 jetson xavier NX深度學習環境配置1. SD卡系統燒錄1.1 材料1.2 軟件配置1.3 格式化SD卡1.4 系統鏡像燒錄 2. 環境配置2.1 cuda環境配置2.2 安裝依賴庫2.3 安裝python及依賴環境2.4 安裝pytorch環境 jetson xavier NX深度學習環境配置 1. SD卡系統燒錄 1.1 材料 SD …

面試題 —— 前端精選(1)

文章目錄 前言 闡述 JS 的事件循環 JS 中的計時器能做到精確計時嗎?為什么? 如何理解 JS 的異步? 前言 本文章介紹三道圍繞 JavaScript 的精選面試題 闡述 JS 的事件循環 事件循環?叫做消息循環,是瀏覽器渲染主線程的?作?式…

CentOS虛擬機重置賬號密碼

虛擬機忘記密碼了 一般來說,虛擬機的賬號密碼,工作中都會有文檔記錄,如果忘記了可以查看文檔。但是也有特例,虛擬機的密碼沒有記錄到文檔中,嘗試了很多次依然登錄失敗,這時候就只能重置賬號密碼了。 1.重…

upload-labs關卡13(基于白名單的0x00截斷繞過)通關思路

文章目錄 前言一、回顧上一關知識點二、靶場第十三關通關思路1、看源代碼2、bp進行0x00截斷繞過3、蟻劍連接 總結 前言 此文章只用于學習和反思鞏固文件上傳漏洞知識,禁止用于做非法攻擊。注意靶場是可以練習的平臺,不能隨意去尚未授權的網站做滲透測試…

nginx中proxy_pass的配置

Nginx的官網將proxy_pass分為兩種類型: 不帶URI方式:只包含IP和端口號的,不帶uri(單個/也算uri),比如proxy_pass http://localhost:8080;帶URI方式:在端口號之后有其他路徑的&#…

思維模型 潘多拉效應

本系列文章 主要是 分享 思維模型 ,涉及各個領域,重在提升認知。越是禁止,越是好奇。 1 潘多拉效應的應用 1.1 潘多拉效應在管理中的應用 通用電氣公司曾經推出了一項名為“六西格瑪”的管理方法,該方法旨在通過優化業務流程和提…

Linux終端和命令行

文章目錄 學習Linux終端和命令行一、常用Linux命令的基本使用(一)放大/縮小終端窗口的字體顯示(二)自動補全 二、軟件安裝三、文件和目錄常用命令(一)ls:查看目錄內容1.ls命令說明2.Linux下文件…

Peter算法小課堂—前綴和數組的應用

桶 相當于計數排序&#xff0c;看一個視頻 桶排序 太戈編程1620題 算法解析 #include <bits/stdc.h> using namespace std; const int R11; int cnt[R];//cnt[t]代表第t天新增幾人 int s[R];//s[]數組是cnt[]數組的前綴和數組 int n,t; int main(){cin>>n;for(…

flutter 輸入框組件 高度問題

使用的組件名字為 TestField 組件 TestField 配置 占位文字 設置 decoration 屬性 InputDecoration 中hintText去掉輸入到 輸入框的間距 InputDecoration 中contentPadding EdgeInsets.zero去掉邊框中的間距 InputDecoration 中 使用 isDense:true設置輸入框內文字的顏色 …

Android 11.0 SystemUI 去掉狀態欄wifi流量上下行圖標功能實現

1.概述 在11.0系統定制rom開發中,在關于systemui的定制功能總,在SystemUI 狀態欄上顯示時鐘,電池電量 wifi圖標,在顯示wifi圖標時,網絡實時更新時,但是會時不時顯示上下行圖標 顯得很不美觀,客戶需求要求不顯示上下行圖標,所以需要去掉上下行圖標功能,接下來實現相關功能…

MATLAB算法實戰應用案例精講-【圖像處理】計算機視覺(基礎篇)(二)

目錄 知識儲備 opencv基礎知識 01 什么OpenCV 02 如何部署OpenCV? 03 OpenCV模塊簡介 04 OpenCV基本數據結構

Shell循環:for(一)

語法結構&#xff1a; for 變量名 [ in 取值列表] do 循環體 done 示例1&#xff1a; 1、需求&#xff1a;自動循環創建10個用戶 2、演示&#xff1a; [rootlocalhost ~]# vim for.sh #腳本編寫 #!/bin/bash for i in {1..10} do useradd "user$…

Linux進程通信之共享內存

文章目錄 共享內存原理申請共享內存函數&#xff08;shmget&#xff09;參數key生成key值示例申請共享內存 掛接到進程地址空間函數(shmat)去關聯函數(shmdt)控制共享內存(shmctl)IPC_STATIPC_RMID ipcs其余進程獲取該共享內存進程間通信 進程間通信&#xff1a;IPC&#xff0c…

在openSUSE-Leap-15.5-DVD-x86_64中使用deepin-wine-6.0.0.19再使用金山打字通2016

在openSUSE-Leap-15.5-DVD-x86_64中使用deepin-wine-6.0.0.19再使用金山打字通2016 在openSUSE Software官網輸入關鍵字deepin-wine搜索得到fedora-deepin-wine6的作者是xuthus5 https://software.opensuse.org/package/fedora-deepin-wine6 在百度貼吧fedora吧的《fedora下的…

C++11『lambda表達式 ‖ 線程庫 ‖ 包裝器』

?個人主頁&#xff1a; 北 海 &#x1f389;所屬專欄&#xff1a; C修行之路 &#x1f383;操作環境&#xff1a; Visual Studio 2022 版本 17.6.5 文章目錄 &#x1f307;前言&#x1f3d9;?正文1.lambda表達式1.1.仿函數的使用1.2.lambda表達式的語法1.3.lambda表達式的使用…

數據結構-深度優先搜索Java實現

目錄 一、引言二、算法步驟三、原理演示遞歸實現非遞歸實現&#xff08;使用堆棧&#xff09; 四、代碼實戰五、結論 一、引言 深度優先搜索&#xff08;DFS&#xff09;是一種在圖或樹中進行搜索的算法&#xff0c;它沿著樹的深度遍歷樹的節點&#xff0c;盡可能深的搜索樹的分…

使用C++從0到1實現人工智能神經網絡及實戰案例

引言 既然是要用C++來實現,那么我們自然而然的想到設計一個神經網絡類來表示神經網絡,這里我稱之為Net類。由于這個類名太過普遍,很有可能跟其他人寫的程序沖突,所以我的所有程序都包含在namespace liu中,由此不難想到我姓劉。在之前的博客反向傳播算法資源整理中,我列舉…

CTF-PWN-QEMU-前置知識

文章目錄 QEMU 內存管理(QEMU 如何管理某個特定 VM 的內存)MemoryRegion gpa->hpaFlatView&#xff1a;表示MR 樹對應的地址空間FlatRange&#xff1a;存儲不同MR對應的地址信息AddressSpace&#xff1a;不同類型的 MemoryRegion樹RAMBlock總體簡化圖 QEMU 設備模擬 &#x…

【Java進階開發實戰】用Java中的Base64數據加密與解密處理

簡介 ? Base64編碼,是我們程序開發中經常使用到的編碼方法。它是一種基于用64個可打印字符來表示二進制數據的表示方法。它通常用作存儲、傳輸一些二進制數據編碼方法, 也是MIME(多用途互聯網郵件擴展,主要用作電子郵件標準)中一種可打印字符表示二進制數據的常見編碼方法…

Proteus下仿真AT89C51報“串行口通信失敗,請檢查電平適配是否正確。”解決辦法

在Proteus下進行AT89C51串行口仿真時&#xff0c;如果遇到“串行口通信失敗&#xff0c;請檢查電平適配是否正確”的錯誤提示&#xff0c;以下是一些解決辦法&#xff1a; 1. 了解AT89C51和外部設備的電平要求&#xff1a; 首先&#xff0c;了解AT89C51和外部設備之間的電平…