Python與設計模式--原型模式

4-Python與設計模式–原型模式

一、圖層

大家如果用過類似于Photoshop的平面設計軟件,一定都知道圖層的概念。圖層概念的提出,
使得設計、圖形修改等操作更加便利。設計師既可以修改和繪制當前圖像對象,又可以保留其它
圖像對象,邏輯清晰,且可以及時得到反饋。本節內容,將以圖層為主角,介紹原型模式。

首先,設計一個圖層對象。

class simpleLayer:background=[0,0,0,0]content="blank"def getContent(self):return self.contentdef getBackgroud(self):return self.backgrounddef paint(self,painting):self.content=paintingdef setParent(self,p):self.background[3]=pdef fillBackground(self,back):self.background=back

在實際的實現中,圖層實現會很復雜,這里僅介紹相關的設計模式,做了比較大的抽象,用
background表示背景的RGBA,簡單用content表示內容,除了直接繪畫,還可以設置透明度。

新建圖層,填充藍底并畫一只狗,可以簡單表示如下:

if  __name__=="__main__":dog_layer=simpleLayer()dog_layer.paint("Dog")dog_layer.fillBackground([0,0,255,0])print "Background:",dog_layer.getBackgroud()print "Painting:",dog_layer.getContent()

打印如下: Background: [0, 0, 255, 0] Painting: Dog

接下來,如果需要再生成一個同樣的圖層,再填充同樣的顏色,再畫一只同樣狗,該如何做呢?
還是按照新建圖層、填充背景、畫的順序么?或許你已經發現了,這里可以用復制的方法來實現,
而復制(clone)這個動作,就是原型模式的精髓了。

按照此思路,在圖層類中新加入兩個方法:clone和deep_clone

from copy import copy, deepcopy
class simpleLayer:background=[0,0,0,0]content="blank"def getContent(self):return self.contentdef getBackgroud(self):return self.backgrounddef paint(self,painting):self.content=paintingdef setParent(self,p):self.background[3]=pdef fillBackground(self,back):self.background=backdef clone(self):return copy(self)def deep_clone(self):return deepcopy(self)
if  __name__=="__main__":dog_layer=simpleLayer()dog_layer.paint("Dog")dog_layer.fillBackground([0,0,255,0])print "Background:",dog_layer.getBackgroud()print "Painting:",dog_layer.getContent()another_dog_layer=dog_layer.clone()print "Background:", another_dog_layer.getBackgroud()print "Painting:", another_dog_layer.getContent()

打印結果如下: Background: [0, 0, 255, 0] Painting: Dog Background: [0, 0,
255, 0] Painting: Dog

clone和deep_clone有什么區別呢?

大多數編程語言中,都會涉及到深拷貝和淺拷貝的問題,一般來說,淺拷貝會拷貝對象內容及其內容的引用或者
子對象的引用,但不會拷貝引用的內容和子對象本身;而深拷貝不僅拷貝了對象和內容的引用,也會拷貝引用的
內容。所以,一般深拷貝比淺拷貝復制得更加完全,但也更占資源(包括時間和空間資源)。舉個例子,
下面的場景,可以說明深拷貝和淺拷貝的區別。
if  __name__=="__main__":dog_layer=simpleLayer()dog_layer.paint("Dog")dog_layer.fillBackground([0,0,255,0])print "Original Background:",dog_layer.getBackgroud()print "Original Painting:",dog_layer.getContent()another_dog_layer=dog_layer.clone()another_dog_layer.setParent(128)another_dog_layer.paint("Puppy")print "Original Background:", dog_layer.getBackgroud()print "Original Painting:", dog_layer.getContent()print "Copy Background:", another_dog_layer.getBackgroud()print "Copy Painting:", another_dog_layer.getContent()

打印如下:

Original Background: [0, 0, 255, 0] Original Painting: Dog Original
Background: [0, 0, 255, 128] Original Painting: Dog Copy Background:
[0, 0, 255, 128] Copy Painting: Puppy

淺拷貝后,直接對拷貝后引用(這里的數組)進行操作,原始對象中該引用的內容也會變動。如果將another_dog_layer=dog_layer.clone()換成another_dog_layer=dog_layer.deep_clone(),即把淺拷貝換成深拷貝,其如果如下:

Original Background: [0, 0, 255, 0] Original Painting: Dog Original
Background: [0, 0, 255, 0] Original Painting: Dog Copy Background: [0,
0, 255, 128] Copy Painting: Puppy

深拷貝后,其對象內的引用內容也被進行了復制。

二、原型模式

原型模式定義如下:用原型實例指定創建對象的種類,并且通過復制這些原型創建新的對象。
需要注意一點的是,進行clone操作后,新對象的構造函數沒有被二次執行,
新對象的內容是從內存里直接拷貝的。

三、原型模式的優點和使用場景

3.1 優點:

1、性能極佳,直接拷貝比在內存里直接新建實例節省不少的資源;
2、簡化對象創建,同時避免了構造函數的約束,不受構造函數的限制直接復制對象,
是優點,也有隱患,這一點還是需要多留意一些。

3.2 使用場景:

1、對象在修改過后,需要復制多份的場景。如本例和其它一些涉及到復制、粘貼的場景;
2、需要優化資源的情況。如,需要在內存中創建非常多的實例,可以通過原型模式來減少資源
消耗。此時,原型模式與工廠模式配合起來,不管在邏輯上還是結構上,都會達到不錯的效果;
3、某些重復性的復雜工作不需要多次進行。如對于一個設備的訪問權限,多個對象不用各申請一遍
權限,由一個設備申請后,通過原型模式將權限交給可信賴的對象,既可以提升效率,
又可以節約資源。

四、原型模式的缺點

1、深拷貝和淺拷貝的使用需要事先考慮周到;
2、某些編程語言中,拷貝會影響到靜態變量和靜態函數的使用。

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

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

相關文章

在 Ubuntu 上安裝最新版的 Calibre

目錄 前言 方法1:從 Ubuntu 的倉庫安裝 Calibre 卸載 Calibre 方法2:獲取最新版本的 Calibre 卸載 Calibre 結語 前言 Calibre 是一款自由開源的電子書軟件。下面介紹如何在 Ubuntu Linux 上安裝它。 作為電子書管理的瑞士軍刀,Calibre …

線程-Thread類及常見方法

目錄 一、創建線程 1.繼承 Thread 類 2. 實現 Runnable 接口 3.匿名內部類創建 Thread 子類對象 4. 匿名內部類創建 Runnable 子類對象 5. lambda 表達式創建 Runnable 子類對象 二、Thread 類及常見方法 2.1 Thread 的常見構造方法 2.2 Thread 的幾個常見屬性 2.3 啟…

C++初級項目webserver項目流程介紹(2)

一、引言 C的webserver項目是自己在學完網絡編程后根據網課的內容做的一個初級的網絡編程項目。 這個項目的效果是可以在瀏覽器通過輸入網絡IP地址和端口,然后打開對應的文件目錄 效果如下: 也可以打開文件夾后點擊目錄,打開到對應的文件夾…

Vue中項目進行文件壓縮與解壓縮 (接口返回文件的url壓縮包前端解析并展示出來,保存的時候在壓縮后放到接口入參進行保存)

安裝 npm install pako在Vue組件中引入pako: import pako from pako;接口返回的url是這個字段 tableSsjsonUrl 其實打開就是壓縮包const source await tableFileUrl ({ id: this.$route.query.id}); if(source.code 0) {this.titleName source.data.tableNam…

ES之x-pack-core-7.14.2許可證修改為白金版

X-Pack是什么 X-pack是elasticsearch的一個擴展包,將安全,警告,監視,圖形和報告功能捆綁在一個易于安裝的軟件包中,雖然x-pack被設計為一個無縫的工作,但是你可以輕松的啟用或者關閉一些功能。 主要分一下步…

WebSocket 鑒權策略與技巧詳解

WebSocket 作為實時通信的利器,越來越受到開發者的青睞。然而,為了確保通信的安全性和合法性,鑒權成為不可或缺的一環。本文將深入探討 WebSocket 的鑒權機制,為你呈現一攬子的解決方案,確保你的 WebSocket 通信得心應…

【Qt之QTextDocument】使用及表格顯示富文本解決方案

【Qt之QTextDocument】使用 描述常用方法及示例使用QTextList使用QTextBlock使用QTextTable表格顯示富文本結論 描述 QTextDocument類保存格式化的文本。 QTextDocument是結構化富文本文檔的容器,支持樣式文本和各種文檔元素,如列表、表格、框架和圖像。…

CANopen協議【SDO】

SDO: SDO是讀寫單個寄存器。主要用于配置伺服驅動器參數。 1 收發功能: //public unsafe struct VCI_CAN_OBJ //CAN數據幀 【單幀對象】//{// public uint ID;// 幀ID。 【11bit】數據右對齊。 詳情請參照: 《8.附件1&#xff1…

Python 模塊

目錄 模塊 6.1. 模塊詳解 6.1.1. 以腳本方式執行模塊 6.1.2. 模塊搜索路徑 6.1.3. “已編譯的” Python 文件 6.2. 標準模塊 6.3. dir() 函數 6.4. 包 6.4.1. 從包中導入 * 6.4.2. 相對導入 6.4.3. 多目錄中的包 模塊 退出 Python 解釋器后,再次進入時&a…

手把手教你安裝 Visual Studio 2022 及其簡單使用

軟件下載 打開 Visual Studio 官網,個人選擇免費的Community社區版就夠用了。 軟件安裝 雙擊運行安裝程序: 點擊繼續 即可: 等待加載完成: 可以看到 Visual Studio 2022 對應不同的開發需求提供了若干工作負載,這里以…

?3ds Max插件CG MAGIC圖形板塊為您提升線條效率!

?通過3ds Max軟件進行繪圖操作時,大多絆住各位設計師們作圖速度的往往都是一些細微的瑣事,重復一變一變的調整修改等問題。 今天說到這個繪圖線條來回調整解決方法就是3ds Max插件CG MAGIC。 Max插件CG MAGIC作為一款智能化的輔助插件,致力于…

flutter編譯和構建鴻蒙應用程序(windows環境)

flutter編譯和構建鴻蒙應用程序(windows環境) 問題背景 針對 OpenHarmony 的 Flutter 版本已經開源,參考 https://gitee.com/openharmony-sig/flutter_flutter。 本文為實踐該流程,實現flutter打包鴻蒙hap包的流程。目前流程已經…

flink的java.lang.IllegalStateException: Buffer pool is destroyed 異常

背景 最近flink的在線應用出現錯誤java.lang.IllegalStateException: Buffer pool is destroyed,本文記錄下這個錯誤的原因 錯誤原因 詳細的日志堆棧如下: Caused by: java.lang.IllegalStateException: Buffer pool is destroyed. at org.apache.flink.runtime…

Ps:畫筆工具的基本操作

畫筆工具 Brush Tool是 Ps 中最常用的工具,廣泛地用于繪畫與修飾工作。 雖然多數操作可在畫筆工具的工具選項欄中選擇執行,但是如果能記住相應的快捷鍵可大大提高工作效率。 熟練掌握畫筆工具的操作對于使用其他工具也非常有益,因為 Ps 中許多…

CSS-長度單位篇

px:像素em:相對元素font-size的倍數rem:相對根字體大小,html標簽就是根%:相對父元素計算 注意:CSS中設置長度,必須加單位,否則樣式無效!

Maven - 打包之爭:Jar vs. Shade vs. Assembly

文章目錄 Pre概述Jar 打包方式_maven-jar-pluginOverview使用官方文檔 Shade 打包方式_maven-shade-pluginOverview使用將部分jar包添加或排除將依賴jar包內部資源添加或排除自動將所有不使用的類排除將依賴的類重命名并打包進來 (隔離方案)修改包的后綴…

ElasticSearch之cat component templates API

命令樣例如下: curl -X GET "https://localhost:9200/_cat/component_templates?vtrue&pretty" --cacert $ES_HOME/config/certs/http_ca.crt -u "elastic:ohCxPHQBEs5*lo7F9"執行結果輸出如下: name …

Qt/QML編程學習之心得:一個QML工程的學習筆記(十)

前言: 到底什么是Qt Quick呢?因為Qt Quick是Qt新引入的,Qt Quick由Qt Quick模塊提供,它是一個編寫QML應用的標準庫。Qt Quick模塊提供了兩種接口:使用QML語言創建應用的QML接口和使用C++語言擴展QML的C++接口。使用Qt Quick模塊,設計人員和開發人員可以輕松地構建流暢的…

【自主探索】基于 frontier_exploration 的單個機器人自主探索建圖

文章目錄 一、概述1、功能2、要求 二、使用方法1、用于運行演示2、用于開發人員2.1. 探索無/地圖數據2.2. 使用 /map 數據進行探索 三、提供的組件1、explore_client1.1. 調用的操作1.2. 訂閱主題1.3. 發布主題 2、explore_server2.1. 提供的操作2.2. 調用的操作2.3. 調用的服務…

【科技素養】藍橋杯STEMA 科技素養組模擬練習試卷6

1、將一個空塑料袋與一個裝滿空氣的塑料袋放到秤上稱重。在兩個塑料袋本身完全一樣的情況下,得出的結果會是 A、空塑料袋更重 B、裝滿空氣的塑料袋更重 C、兩個塑料袋一樣重 D、無法判斷 答案:C 2、全球變暖帶來的一個主要影響就是海平面的上升。造…