设计模式 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
young1
V2EX    程序员

设计模式

  •  
  •   young1 2024-12-02 21:41:15 +08:00 4420 次点击
    这是一个创建于 366 天前的主题,其的信息可能已经有所发展或是发生改变。
    怎样才能学好设计模式,有什么好的教程推荐呢,各位大佬
    33 条回复    2024-12-04 10:17:48 +08:00
    chihiro2014
        1
    chihiro2014  
       2024-12-02 23:50:32 +08:00   1
    根据业务重构代码,重构的多了,自然懂了
    kissthekidlu
        2
    kissthekidlu  
       2024-12-02 23:54:54 +08:00
    先从 clean code 学起.多写,多写,换个方法写,换个方法写.
    你的代码肯定有些代码可以重构到 command 设计模式,或者 factory 设计模式.
    强写几次,就上手了.
    mitoop
        3
    mitoop  
       2024-12-02 23:57:57 +08:00 via iPhone
    看过很多个版本的设计模式,包括不同语言的,久久都不能彻底明白,甚至有的版本的讲解还会带来更多的困惑,直到看到了这位老哥 https://github.com/zhangyue0503/designpatterns-php 的版本似乎一下子通窍了,我主要语言是 php ,又反复琢磨了多次,先对最熟悉的下手,对 laravel 框架源码进行了多次分析用了哪些设计模式,前期每隔一段又去复习下,现在基本熟悉了。
    yooomu
        4
    yooomu  
       2024-12-03 00:16:13 +08:00
    这个确实需要在开发过程中实践,等你成功用设计模式重构了一段一团乱麻的代码,你就会豁然开朗
    mitoop
        5
    mitoop  
       2024-12-03 00:17:35 +08:00 via iPhone   1
    设计模式非常灵活,但都有固定的特征,也经常多个模式组合使用。例如 laravel 的 auth 认证,它支持多种 guard ,session ,jwt 等,从这个角度看这是策略模式,把 guard 理解为抽象的算法,可以互相替换或者新增 guard 。对于 AuthManager 它又是一个简单工厂模式,因为要根据不同的 guard type 创建对应的类,简单工厂又有开闭的问题,他又有 extend 方法来解决简单工厂的开闭问题。
    BeautifulSoap
        6
    BeautifulSoap  
       2024-12-03 00:24:51 +08:00   4
    没有写过较多项目或者参与较复杂项目的经验,学设计模式学了等于白学,因为没有相应的前置知识和经验积累,学这东西就是在死记硬背

    等你有了相应项目经验了,看设计模式基本就下面两种反应

    1. 要么:哦!对!我工作上项目上次就遇到相关问题,的确用这种方法来可能更好点
    2. 要么:啊?!就这也配叫模式?! 这不是脑子正常点的人,代码写多了自然而然就想出来的写法吗,就这还值得专门给他分配个 xxx 模式的名字吗? (对,我说的就是我第一次看设计模式里工厂模式,singleton 模式的感想)
    liuliuliuliu
        7
    liuliuliuliu  
    PRO
       2024-12-03 00:31:11 +08:00
    先看一遍,然后要做,要思考,多重构,多重构,多重构
    oisadfo
        8
    oisadfo  
       2024-12-03 06:44:35 +08:00 via Android
    设计模式是答案,如果没有问题有答案也没有用
    daysv
        9
    daysv  
       2024-12-03 08:42:12 +08:00
    什么设计模式, 不存在的, 所有的东西都是函数, 一个函数不够就拆两个。
    主打一个万金油
    qiumaoyuan
        10
    qiumaoyuan  
       2024-12-03 09:09:10 +08:00
    这种东西看看就完了。
    xNzkYyo6Rh84I83G
        11
    xNzkYyo6Rh84I83G  
       2024-12-03 09:10:57 +08:00
    求个 Javascript 的设计模式
    Edward4074
        12
    Edward4074  
       2024-12-03 09:15:05 +08:00   1
    就是武侠小说里,你以为比的是招式(设计模式),实际上比的是内力(思维模式)
    LwZiye
        13
    LwZiye  
       2024-12-03 09:18:08 +08:00
    看下大话设计模式,从场景上思考解决问题的思路。
    nxforce
        14
    nxforce  
       2024-12-03 09:24:56 +08:00   1
    这玩意真是学一次忘一次,只有代码量上来了才会用,设计模式更多是一种 OOP 设计的共识,接触时间长了,场景多了,在工程化过程中就会无意识地使用到一些设计模式,无需刻意去用。
    felbryiozzzz
        15
    felbryiozzzz  
       2024-12-03 09:25:26 +08:00
    newaccount
        16
    newaccount  
       2024-12-03 09:46:58 +08:00
    head first: design pattern
    有中文版
    smileeast
        17
    smileeast  
       2024-12-03 10:07:18 +08:00
    @BeautifulSoap #6 确实,写代码就是走量的同时开始思考那种方法写的简单,好,不断的写,对比就知道了,单单的去先看设计模式相关的书,完全没必要,浪费时间
    lyxxxh2
        18
    lyxxxh2  
       2024-12-03 10:10:46 +08:00
    我赞同 14 楼,一种共识而已。
    学设计模式,必须 2-3 年经验+。
    踩过一些坑,才知道设计模式能解决什么。
    至于啥优雅的,强行上还不如不上。

    1. 理解目的
    2. 根据自己理解,手写个出来。
    3. 后面该用时,就会想到
    [php 设计模式学习 ]( https://learnku.com/docs/study-php-design-patterns/1.0)
    之前学的。
    guanzhangzhang
        19
    guanzhangzhang  
       2024-12-03 10:18:38 +08:00
    kushu001
        20
    kushu001  
       2024-12-03 10:48:44 +08:00
    入坑 DDD,领域设计驱动开发,里面会用到非常多的模式
    比如:
    单例模式,命令模式,工厂模式,仓储模式,依赖倒置,cqrs, 观察者模式等等,非常多,
    设计模式说白了就是写代码过程中的一种经验总结,平时如果只写 CRUD 可能很难接触到这块的内容,
    直接自己写框架,就能体会了,因为框架就需要用到很多设计模式来处理你的框架上碰到的问题,
    如果不嫌弃,可以看一下我写的,因为 DDD 本身概念的东西比较多,落地也非常困难,我也是通过我几年学习 DDD 的经验积累写的,如果有觉得写的不好的地方,也希望各位能够批评指正
    gitee: https://gitee.com/neegix-opensource-group/nebula-framework
    github: https://github.com/NeegixOpensourceGroup/nebula-framework
    gitcode: https://gitcode.com/NeegixOpensourceGroup/nebula-framework
    wjfz
        21
    wjfz  
       2024-12-03 12:58:09 +08:00
    @BeautifulSoap #6 那两种反应太真实了
    lz234561
        22
    lz234561  
       2024-12-03 15:59:24 +08:00
    大话设计模式,这个确实可以的。
    q8164305
        23
    q8164305  
       2024-12-03 16:45:16 +08:00
    设计模式本质上是可有可无的,如果代码简单,完全不需要任何任何设计模式,设计只是更好的一种组织代码的方式,方便和别人交流,减少沟通成本罢了,只有写了足够多的麻花一样,绕来绕去的代码,重构的时候才能理解设计模式的强大,设计模式只是一种组织代码的结构而已,不是必须的
    0IuL7w7X5K2HJxZf
        24
    0IuL7w7X5K2HJxZf  
       2024-12-03 16:52:34 +08:00
    不用太纠结,当行业黑话来理解。
    mascteen
        25
    mascteen  
       2024-12-03 16:55:03 +08:00
    用函数编程,设计模式只有一个, 就是函数
    NoOneNoBody
        26
    NoOneNoBody  
       2024-12-03 17:18:57 +08:00
    设计模式的主要思想是抽象化,写通用代码时用的,如果业务流程非常独特,就没必要了

    项目使用设计模式 A
    如果项目大更新,就要换一个设计模式 B ,那设计模式 A 对于该项目来说,就是专有的,并非通用的,这个 A 其实就是没必要的
    如果项目大更新,仍然能使用 A ,只是改动模块,甚至模块换了新技术也能延续,这个 A 才是通用的

    例如
    设计模式目标是人员管理,项目初始为学生,第一次更新需要拓展到交换生,第二次更新需要拓展到教师,第三次更新需要拓展到校工……多次更新,只需要修改或添加少量模块,那么这个设计模式才是通用的
    如果每次更新都要重写,例如最初是单例,第一次变为装饰器,第二次变为共享,第三次变为组合……不是不可以,只是模式变,思维和逻辑也跟着变,就没有“设计”了,只是每次推倒重来而已
    所以设计模式需要一定大局观和预见性,能从一堆不同的东西抽象出共性的东西

    又如
    有多个函数,各自的目的、计算都不同,但它们有个共同的特征:都是两个参数,一个为序列,一个为单值,返回都是序列。这样,其实可以抽象出一个闭包函数 func(array, value),返回序列
    同理可以造一个抽象类,将不同的实际类(学生类、教师类、校工类),都能套上
    抽象类作为入口,根据实际情况,可能是平衡的,可能是有序的,可能是父子的,使用不同的实际类处理数据,完成这个或多个抽象类及其实现过程,就是设计模式了

    现实中的各种模板,就是设计模式的实例,例如下载个开源商城,你卖食品、工业品、虚拟品,什么都能套上,这个开源商城就是用一套设计模式写成的,它里面变化的只是商品数据、商品分类以及支付方式
    还有各种论坛源码等等都是
    计算机语言本身就是一个设计模式,不同语言基本都离不开 变量、表达式、命令句、函数……这些共性的东西

    题外:汉语成语就是抽象类,能把不同的人想表达的长句、组句、甚至上百字的解释,抽象为四个字。只要说的和听的都懂这个成语,双方就能顺利沟通。
    所以#14 所说的“共识”也是对的,他甚至把我上面这一大段话抽象为两个字了
    Oktfolio
        27
    Oktfolio  
       2024-12-03 17:28:58 +08:00
    div class="reply_content">风气变了?怎么 20 个小时了还没人出来骂 Java?
    sillydaddy
        28
    sillydaddy  
       2024-12-03 18:09:50 +08:00
    如果你仔细观察那么多设计模式,会发现它们基本上都是在讲一件事:接口的抽象、分层、去耦合, 就像 #26 楼 @NoOneNoBody 说的。把这点仔细研究研究,就豁然开朗了。

    举几个例子,

    「观察者模式」: 某个对象变动了,通知其他对象(或者说其他对象观察某个对象的变动)。 这种“一变动就通知”的机制,主要用于底层对象向上层对象发送通知,对于这些通知,无论上层对象是处理还是不处理,无论上层具体怎样处理,都跟底层对象没有关系了。所以观察者模式,其实是将底层对象的向上通知这种(接口)行为统一抽象出来了,而且去掉了底层与上层的耦合。
    「访问者模式」:将被访问的数据结构的遍历抽象出来了,上层要访问某个比较固定的数据结构的时候,不用每个访问者把遍历这个数据结构的代码都重复写一遍,只需要写出来对该数据结构如何具体操作,遍历这个数据结构的过程已经被“访问者模式”抽象和剥离出来了。像 C++ stl 的迭代器也可以算是非常典型的访问者模式,只需要 iterator++就可以,不用关心底层是 vector 还是 list 。
    「工厂模式」:这个就更直接了,传给工厂一个不同的参数,生成一个与之对应的实例,并且这些实例都实现了一个相同的接口。具体生产哪个类的实例不需要关心,唯一需要关心的就是,传入一个不同的参数,得到同一个接口的不同实现,经过这种抽象后,工厂模式对外呈现出一种极为简洁的形式:不同参数->接口的不同实现。


    所以学习的时候,只要仔细留心接口是怎样抽象的,接口抽象出来后,达到了什么目的和效果,就可以了,不用特意记各种设计模式,死记也记不住。
    Leviathann
        29
    Leviathann  
       2024-12-03 18:15:17 +08:00
    @mascteen 那各种 Monad 、functor 、typeclass 算什么
    securityCoding
        30
    securityCoding  
       2024-12-03 18:41:08 +08:00
    不知道执着这个东西 ,堆久了都是
    Nosub
        31
    Nosub  
       2024-12-03 19:00:29 +08:00 via iPhone
    刚好今年我阅读了一本设计模式的书籍《 C++ Software Design 》,我认为把设计模式讲的最深刻的,只有英文版。

    https://nosub.net/posts/p/160
    usVexMownCzar
        32
    usVexMownCzar  
       2024-12-03 19:06:17 +08:00
    [免费在线学习代码重构和设计模式]( https://refactoringguru.cn/)

    这个网站设计模式有中文,代码重构没有

    代码示例部分的语言包含了 C# C++ Go JAVA PHP Python Ruby Rust Swift TS
    mascteen
        33
    mascteen  
       364 天前
    @Leviathann 函数用多了之后,自然的衍生,他并不是什么新的东西,只是一个概念名词
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2922 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 13:48 PVG 21:48 LAX 05:48 JFK 08:48
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86