編程教室開了這麼久,已經有不少人從徹底零基礎的小白成爲了會寫代碼的菜鳥程序員,可以本身獨立開發程序。不過到此階段,經常會遇到瓶頸,感受功能能夠實現,但代碼看起來有些彆扭:程序員
代碼中有不少類似的重複代碼
代碼中有大量的 if,以致於有很長的縮進
單個代碼寫得很長,別人很難看懂,過陣子可能本身都看不懂
總會有沒有考慮到的狀況致使 bug
修復一個 bug 又會產生新的 bug
單個功能能夠實現,但多個功能組合在一塊兒就理不清
若是需求發生變更,代碼修改起來很麻煩
有多種實現方式時不知道該用哪種
很難和其餘人協做開發
上述的問題你是否是有過相似困擾?解決的辦法其實也簡單,就是堅持「多寫」和「多讀」:面試
多寫代碼。不少時候你以爲很差處理,並非由於高深的問題,只是你對代碼的基本使用還不夠熟練。一樣的問題,踩過坑再爬出來,反覆幾回天然你也知道怎麼繞開了。
多讀代碼。除了本身寫,看看別人的代碼也會學到不少。包括教程裏的案例、官方示例、開源項目的源碼等。所謂「熟讀唐詩三百首,不會做詩也會吟」嘛。
除了這兩個「笨辦法」外,還有樣東西,對於處在這個階段的你或許有很大啓發,這就是:編程
設計模式是對於軟件開發中常見的一些問題所總結出的解決方案,它並不關注具體的代碼怎麼寫,而是代碼的結構應該如何設計,從而讓代碼更加可靠、可讀、可重用、易於維護。它不是一種嚴格意義上的「技術」,而是一門「經驗主義」,也就是開發者常常提到的「最佳實踐」。因此設計模式其實就是在前人各類踩坑經驗之上,總結出的各類開發「套路」。設計模式
舉幾個常見的設計模式例子:性能優化
單例模式架構
場景舉例:代碼中須要一個共享的資源管理器,保證在代碼只有惟一的一個實例,且代碼各處均可以訪問到。併發
若是你的代碼只有一個文件,可能不會趕上這個問題。但當項目大一點以後,這個問題十分常見。你能夠選擇定義一些全局變量來實現。但更好的「套路」是使用單例模式:它能夠保證只建立一個對象(第一次訪問時建立,以後訪問時直接返回已有對象),並提供全局的訪問。分佈式
代碼演示微服務
# 單例類 class Singleton(object): _instance = None def __new__(cls, *args, **kw): if not cls._instance: cls._instance = super(Singleton, cls).__new__(cls, *args, **kw) return cls._instance # 繼承單例 class MyClass(Singleton): a = 1 # 使用 mc1 = MyClass() mc2 = MyClass() print(mc1==mc2) mc1.a += 1 print(mc2.a) 輸出 True 2
場景舉例:在一個繪圖工具裏,有不一樣的筆刷。當點擊不一樣的筆刷按鈕時,須要建立對應的筆刷供使用。高併發
若是把每一個按鈕響應裏都去單首創建,代碼會很冗餘且不利於維護。這時可建立一個「工廠」類,將建立筆刷的代碼放在其中,只須要根據傳入的參數不一樣,返回不一樣的筆刷實例便可。就如同工廠根據訂單生產產品同樣。
代碼演示
筆刷工廠,具體類代碼略
def pen_factory(mode): if mode == 'PEN': return Pen() elif mode == 'PENCIL': return Pencil() elif mode == 'BRUSH': return Brush() else: return None 使用 p = pen_factory('BRUSH')
場景舉例:開發一個論壇,容許用戶在帖子中上傳圖片,因而須要提供保存圖片的功能。
通常爲了網站的訪問速度,會選擇第三方的圖片保存服務。那麼在保存圖片的時候,就須要調用其提供的接口。而應用代理模式的話,就會在網站和第三方服務間增長一層。這樣的好處是能夠將一些額外的處理放在代理層中,當須要更換第三方服務時,不須要修改網站的邏輯,只要調整代理層便可。
代碼演示
class ImgService: @abstractmethod def save(self, img): pass # 真實類 class XYZImgService(ImgService): def save(self, img): # 調用第三方服務接口 # 代理類 class ImgServiceProxy(ImgService): def __init__(self): self.service = XYZImgService() def save(self, img): return self.service.save(img) # 使用 def save_img(img): proxy = ImgServiceProxy() proxy.save(img)
設計模式的六大原則:
一、開閉原則(Open Close Principle)
對擴展開放,對修改關閉。在需求變更時,儘量不修改原有代碼,而經過擴展實現。
二、里氏代換原則(Liskov Substitution Principle)
在使用繼承時,在子類中儘可能不要重寫和重載父類的方法。
三、依賴倒轉原則(Dependence Inversion Principle)
針對接口編程,細節依賴於抽象。
四、接口隔離原則(Interface Segregation Principle)
下降類之間的耦合度,不依賴沒必要要的接口。
五、迪米特法則,又稱最少知道原則(Demeter Principle)
模塊之間相互獨立,對本身依賴的類須要知道的信息越少越好。
六、合成複用原則(Composite Reuse Principle)
儘可能使用合成/聚合的方式,而不是使用繼承。
具體的解讀,今天無法在一篇推送中展開詳述,並且這是個須要不斷體會和實踐的事情。首先你能夠找些相關書籍讀一讀。設計模式有一本經典書籍:《Design Patterns: Elements of Reusable Object-Oriented Software》(《設計模式:可複用面向對象軟件的基礎》)。此書又被稱做「GoF」(Gang of Four,四人組),四位業內大牛總結出了 23 種設計模式。
然而,我強烈不推薦新手去看這本書,由於你極可能看不懂。我推薦的是一本叫作《Head first 設計模式》的書,能夠算做上面那本的白話入門版,對於新手來講友好許多,或許幫助更大。
開發者對於設計模式的理解大體存在這樣幾個階段:一開始只關注語法和庫,不懂設計模式,寫代碼無章法;後來瞭解了設計模式以後,開始嘗試套用設計模式,懂得重構代碼,但有時不免教條化或陷入過分設計的誤區;等到開發經驗豐富以後,再也不拘泥於所謂的「模式」,自己寫出的代碼就已經契合設計的原則。
書上的設計模式是一成不變的,不可能涵蓋每一種開發場景,而軟件技術自己也不斷髮展,不少模式已經被新的語言特性所實現。所以也有不少人對於設計模式的價值存在質疑。個人見解是,若是你處在新手階段,學習設計模式是很好的提高方式,也能夠開拓你的編程思惟。而當你已經走上進階之路以後,更多的應是關注模式背後的原則,寫出更合理的代碼,而並不是爲了模式而模式。
固然這一切,仍是都離不開足夠的代碼量。每一個程序員都是一行行代碼堆出來。
順便在此給你們推薦一個Java方面的交流學習羣:957734884,裏面會分享一些高級面試題,還有資深架構師錄製的視頻錄像:有Spring,MyBatis,Netty源碼分析,高併發、高性能、分佈式、微服務架構的原理,JVM性能優化這些成爲架構師必備的知識體系,主要針對Java開發人員提高本身,突破瓶頸,相信你來學習,會有提高和收穫。在這個羣裏會有你須要的內容 朋友們請抓緊時間加入進來吧