感觉自己的代码很乱?因为你不懂套路

简介: 编程教室开了这么久,已经有很多人从完全零基础的小白成为了会写代码的菜鸟程序员,能够自己独立开发程序。不过到此阶段,常常会遇到瓶颈,感觉功能可以实现

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


  • 代码中有很多相似的重复代码
  • 代码中有大量的 if,以至于有很长的缩进
  • 单个代码写得很长,别人很难看懂,过阵子可能自己都看不懂
  • 总会有没有考虑到的情况导致 bug
  • 修复一个 bug 又会产生新的 bug
  • 单个功能可以实现,但多个功能组合在一起就理不清
  • 如果需求发生变动,代码修改起来很麻烦
  • 有多种实现方式时不知道该用哪一种
  • 很难和其他人协作开发


上述的问题你是不是有过类似困扰?解决的办法其实也简单,就是坚持“多写”和“多读”:


  1. 多写代码。很多时候你觉得不好处理,并不是因为高深的问题,只是你对代码的基本使用还不够熟练。同样的问题,踩过坑再爬出来,反复几次自然你也知道怎么绕开了。
  2. 多读代码。除了自己写,看看别人的代码也会学到很多。包括教程里的案例、官方示例、开源项目的源码等。所谓“熟读唐诗三百首,不会作诗也会吟”嘛。


除了这两个“笨办法”外,还有样东西,对于处在这个阶段的你或许有很大启发,这就是:


设计模式


设计模式是对于软件开发中常见的一些问题所总结出的解决方案,它并不关注具体的代码怎么写,而是代码的结构应该如何设计,从而让代码更加可靠、可读、可重用、易于维护。它不是一种严格意义上的“技术”,而是一门“经验主义”,也就是开发者经常提到的“最佳实践”。所以设计模式其实就是在前人各种踩坑经验之上,总结出的各种开发“套路”。


举几个常见的设计模式例子:


单例模式


场景举例:代码中需要一个共享的资源管理器,保证在代码只有唯一的一个实例,且代码各处都可以访问到。


如果你的代码只有一个文件,可能不会遇上这个问题。但当项目大一点之后,这个问题十分常见。你可以选择定义一些全局变量来实现。但更好的“套路”是使用单例模式:它可以保证只创建一个对(第一次访问时创建,之后访问时直接返回已有对象),并提供全局的访问


代码演示


# 单例类
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


之前我们的文章Python单例模式(Singleton)的N种实现有专门讨论过 Python 中的单例模式实现。


工厂模式


场景举例:在一个绘图工具里,有不同的笔刷。当点击不同的笔刷按钮时,需要创建对应的笔刷供使用。


如果把每个按钮响应里都去单独创建,代码会很冗余且不利于维护。这时可创建一个“工厂”类,将创建笔刷的代码放在其中,只需要根据传入的参数不同,返回不同的笔刷实例即可。就如同工厂根据订单生产产品一样。


代码演示


# 笔刷工厂,具体类代码略
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)


设计模式的六大原则


1、开闭原则(Open Close Principle)

对扩展开放,对修改关闭。在需求变动时,尽可能不修改原有代码,而通过扩展实现。


2、里氏代换原则(Liskov Substitution Principle)

在使用继承时,在子类中尽量不要重写和重载父类的方法。


3、依赖倒转原则(Dependence Inversion Principle)

针对接口编程,细节依赖于抽象。


4、接口隔离原则(Interface Segregation Principle)

降低类之间的耦合度,不依赖不必要的接口。


5、迪米特法则,又称最少知道原则(Demeter Principle)

模块之间相互独立,对自己依赖的类需要知道的信息越少越好。


6、合成复用原则(Composite Reuse Principle)

尽量使用合成/聚合的方式,而不是使用继承。


具体的解读,今天没法在一篇推送中展开详述。而且这是个需要不断体会和实践的事情。首先你可以找些相关书籍读一读。设计模式有一本经典书籍:《Design Patterns: Elements of Reusable Object-Oriented Software》(《设计模式:可复用面向对象软件的基础》)。此书又被称作“GoF”(Gang of Four,四人组),四位业内大牛总结出了 23 种设计模式。


然而,我强烈推荐新手去看这本书,因为你很可能看不懂。我推荐的是一本叫做《Head first 设计模式》的书,可以算作上面那本的白话入门版,对于新手来说友好许多,或许帮助更大。



开发者对于设计模式的理解大致存在这样几个阶段:一开始只关注语法和库,不懂设计模式,写代码无章法;后来了解了设计模式之后,开始尝试套用设计模式,懂得重构代码,但有时难免教条化或陷入过度设计的误区;等到开发经验丰富之后,不再拘泥于所谓的“模式”,本身写出的代码就已经契合设计的原则。


书上的设计模式是一成不变的,不可能涵盖每一种开发场景,而软件技术本身也不断发展,很多模式已经被新的语言特性所实现。因此也有很多人对于设计模式的价值存在质疑。我的看法是,如果你处在新手阶段,学习设计模式是很好的提升方式,也可以开拓你的编程思维。而当你已经走上进阶之路之后,更多的应是关注模式背后的原则,写出更合理的代码,而并非为了模式而模式。


当然这一切,还是都离不开足够的代码量。每个程序员都是一行行代码堆出来。




其他内容回复左侧关键词获取:

python :零基础入门课程目录

新手 :初学者指南及常见问题

资源 :超过500M学习资料网盘地址

项目 :十多个进阶项目代码实例


如需了解视频课程及答疑群等更多服务,请号内回复 码上行动

代码相关问题可以在论坛上发帖提问 bbs.crossincode.com

推荐阅读:

爬抖 | AI名画 | 押韵工具 | 虎扑 | 如何debug | 查天气 | 我用Python | 知乎 | 排序 | 电影票 | 技术宅 | 单词表 | 新手建议 | 如何提问 | 中文编程

相关文章
|
2月前
|
设计模式 算法 程序员
如何写出好的代码注释?
作为程序员,想必大家在日常开发中必写注释,而且在软件开发过程中,给代码写注释是一项至关重要的工作,也是一名合格的程序员该具备的编程素养。恰当的注释可以提高代码的可读性和可维护性,方便其他人理解熟悉和修改代码,但是不恰当或过度的注释可能会导致混乱和误导,会起到适得其反的作用。那么本文就来分享一些关于如何正确地给代码写注释的方法和指导原则,并提供一些减少注释但仍能让他人理解代码的方法。
87 3
如何写出好的代码注释?
|
2月前
|
设计模式 Java 开发者
一目了然!谁能想到Java多线程设计模式竟然被图解,看完不服不行
多线程设计模式在Java编程中起着至关重要的作用,它能够有效提高程序的执行效率,使得程序在处理大量数据和复杂任务时更加高效。然而,对于初学者来说,理解和应用多线程设计模式可能是一项相当具有挑战性的任务。为了让读者更加轻松地掌握这一复杂主题,我们带着一种全新的图解方式,深入剖析Java多线程设计模式的精髓。
|
12月前
编程要搞明白的东西(一)
编程要搞明白的东西(一)
60 0
|
12月前
|
Java
编程要搞明白的东西(二)
编程要搞明白的东西(二)
68 0
|
算法 Python
举一反三:三种问题,两个指针,一种方法
举一反三:三种问题,两个指针,一种方法
63 0
|
编解码 前端开发 程序员
为啥只跟着视频敲代码学不好编程?
为啥只跟着视频敲代码学不好编程?
336 1
|
JavaScript 中间件 API
带你从头到尾系统地撸一遍Redux源码(二)
Redux中的中间件思想 要想理解redux 的中间件思想, 我们先 看下compose这个文件做了什么, 这个文件其实做的事情十分简单。主要是用到函数式编程中的组合概念, 将多个函数调用组合成一个函数调用。
带你从头到尾系统地撸一遍Redux源码(二)
|
JavaScript 前端开发 中间件
带你从头到尾系统地撸一遍Redux源码(一)
Redux 背后的Flux 架构思想 看源码首先得明白,Redux背后的架构思想,为什么他和React那么的搭配,我们可以认为 Redux 是 Flux 的一种实现形式(虽然它并不严格遵循 Flux 的设定),理解 Flux 将帮助你更好地从抽象层面把握 Redux。 首先flux架构将一个应用分成4个部分: view:  视图层 action(动作):视图层发出的动作如: mouseclick dispatcher (派发器) :主要是用来接受actions,执行回调函数 store(数据层):用来存放应用的状态,一旦发生变动就要提醒 view 视图层更新 从图中可以看出Flux最大的
带你从头到尾系统地撸一遍Redux源码(一)
|
存储 Java
来自三段代码的疑惑~
来自三段代码的疑惑~
97 0
|
开发者 Python
一日一技:8行炫技代码,知识点多得不得了
一日一技:8行炫技代码,知识点多得不得了
266 0
一日一技:8行炫技代码,知识点多得不得了