不寫垃圾代碼,從學會這個設計模式開始

大家好,我們今天來一起學習一個新的設計模式,叫做媒介模式

所謂的媒介其實是一種封裝的思想,把某些功能共同的邏輯抽象出來做成一箇中間的媒介,從而減少代碼之間的耦合,提升拓展性,更加方便日後的需求變更。

簡單案例

我們用一個實際的例子來認知一下媒介這個設計模式。

假設我們要做一個聊天室,如果真要去做的話,這裏面會非常複雜,涉及到很多網絡編程的知識,比如廣播、客戶端、服務端等等。爲了方便演示,我們把這些都簡化了。這樣簡化到極致之後,我們的聊天室代碼就只有幾行:

class User:
    def __init__(self, name):
        self.name = name
       
    def say(self, message):
        call_something()
        print('[{} says:] {}'.format(self.name, message))

這段邏輯沒什麼好說的,大家應該都能看懂。假設我們就這麼完成了產品經理的需求,會有一個什麼問題呢?

功能上當然是OK的,但是系統設計上有兩個比較大的問題。第一個是邏輯重複的問題,我們在User也就是聊天室中用戶對象的類當中實現了怎麼在聊天室當中聊天的功能。我們會發現用戶之間的私聊,用戶之間的視頻、語言等可能都會用到差不多的邏輯,比如建立網絡連接,比如發送消息,判斷消息是否發送成功等等。

但是現在這些邏輯是寫死在User這個類裏了,如果其他類想要使用,根本沒法複用,只能把代碼拷貝一份。這樣拷貝來拷貝去就會使得代碼變得非常混亂,變得難以維護。

第二個問題是邏輯耦合的問題,User這個類是聊天室的用戶對象類,但是其中實現了很多聊天室的功能。表面上看是簡單了,但其實是聊天室和用戶這兩個不同概念的代碼耦合在一起了。很多垃圾項目都有這個問題,明明A本身就應該是一個單獨的實體,結果我卻需要去修改B當中的代碼。時間一長,連開發者自己都會忘記當初實現某某的邏輯放在哪裏。

通過對這個案例的分析,其實也是對爲什麼要使用設計模式這個問題的回答。設計模式大多數情況下並不能直接提升項目的運行效率,它最大的功能是爲了代碼的拓展性以及可維護性。如果不使用合理的設計模式,隨着功能的增多,項目代碼和逐漸變得越來越臃腫,直到人類難以維護的地步。

媒介模式

迴歸正題,那麼我們怎麼樣來使用媒介設計模式來解決上面的這兩個問題呢?

其實很簡單,我們直接來看代碼吧:

class ChatRoom:

    def display_message(self, user, message):
        print('[{} says]: {}'.format(user, message))


class User:

    def __init__(self, name):
        self.name = name
        self.chat_room = ChatRoom()

    def say(self, message):
        self.chat_room.display_message(self, message)

也就是說我們抽象出了一個ChatRoom這個類,將聊天室的功能從User類當中剝離了出去,並且將它作爲了User類的一個成員變量。這樣做的好處是,當以後聊天室的功能需要複用或者是需要修改的時候,我們可以避免對User類的打擾。不然的話,開發人員需要在User類的一堆代碼當中準確找到聊天室的相關邏輯進行修改,相信我,這絕不是什麼很好的體驗。

當然,到這裏並沒有優化到極致,由於User這個類的實例很多,我們會發現每次我們創建一個User的實例都會產生一個ChatRoom的實例,這其實是非常多餘並且沒有必要的。所以我們可以把ChatRoom設計成單例模式,不管User創建多少實例,獲得的ChatRoom都是同一個,這樣就節省了內存開銷。

我們用單例模式來改寫一下ChatRoom的代碼:

import threading

class ChatRoom:
    _lock = threading.Lock()
    
    def __init__(self):
        pass
    
    
    def __new__(cls, *algs, **kw):
        if not hasattr(ChatRoom, '_instance'):
            with ChatRoom._lock:
                if not hasattr(ChatRoom, '_instance'):
                    ChatRoom._instance = object.__new__(cls)
  return ChatRoom._instance

到這裏,這個問題纔算是被優化到了極限。看似很簡單的一個功能,其實當中涉及的細節和思考還是很多的,絕不是表面上看起來的那麼簡單,這些內容書本上往往是學不到的,只能通過自己的實踐和思考來獲得。

今天的文章就到這裏,衷心祝願大家每天都有所收穫。如果還喜歡今天的內容的話,請來一個三連支持吧~(點贊、關注、轉發

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章