写代码也有“套路”-谈谈设计模式

编程教室开了这么久,已经有不少人从彻底零基础的小白成为了会写代码的菜鸟程序员,可以本身独立开发程序。不过到此阶段,经常会遇到瓶颈,感受功能能够实现,但代码看起来有些别扭:程序员

代码中有不少类似的重复代码
代码中有大量的 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开发人员提高本身,突破瓶颈,相信你来学习,会有提高和收获。在这个群里会有你须要的内容 朋友们请抓紧时间加入进来吧

相关文章
相关标签/搜索