Java & Go 设计模式实现

10 天前
 karashoukpan

用 Java 和 Go 写了 23 种设计模式的例子实现。大家有感兴趣的可以看看看,给个 star ,有想法可以交流讨论下,互相学习 👀

Github 地址: https://github.com/yuluo-yx/design-pattern

3894 次点击
所在节点    程序员
40 条回复
Ketteiron
10 天前
我对设计模式的理解
单例模式:部分落后的面向对象语言特有的反模式,违反单一原则,一个类不仅要实现功能,还需要管理自己的唯一实例。Java 中已由 SpringBoot 解决了底层的垃圾活,如果需要自行实现单例我只会觉得这人的脑袋坏掉了。
大部分情况出自 Java 面试题,经典且无用的八股文,仅仅为了考察根本用不到的懒加载、指令重排。
对于更先进的面向对象语言很好解决,例如 kotlin 的 object ,js 的{},跳过 class 这一步直接创造对象就行了。
至于 Go 呢,package 是单例,sync.Once 可以实现延迟加载。

工厂、建造者、原型模式:Java 有用的设计理念,但是 Go 没有继承/重载,只能写点似是而非的东西。
但作为面试题,这三个只比单例好一点,也几乎没有实际意义。

代理、装饰器模式:由于 SpringBoot ,在 Java 里它们是基础设施,是面试题应该重点考的东西,可以避免一些错误的使用方法。

适配器模式:非常好的理念,编程是在破旧的茅草屋上缝缝补补,拆东墙补西墙,适配器让各种屎山能成功运转起来,是一座丰碑。

很多设计模式我只在自己的玩具项目上尝试引入,确实有些是很好的理念,但工作中我不会自找麻烦。设计模式要为代码实现服务,如果使用了设计模式能少写代码,好写代码,那么是好的,可惜事实并非如此,绝大部分业务/场景的复杂度远达不到 Springboot 框架的程度,强行引入一个又一个设计模式不如去干点更有意义的事。

例如可以折腾下多平台聊天机器人之类的玩具,真心要写得好这些设计模式几乎都会用到。
正常的话是不应该过度使用设计模式的,Java 还好说,Go 去凑合设计模式是没苦硬吃。
如果真的对设计模式情有独钟,就多写点呗,23 种设计模式已经是三十年前的破烂了,要与时俱进挑战一下 62 种:
https://github.com/iluwatar/java-design-patterns
vultr
9 天前
懂道设计模式还是有必要的,用不用是另一回事。
veike
9 天前
关于设计模式如何我亮出这个网站,阁下准备如何应对
https://refactoringguru.cn/
pengtao2001
9 天前
@veike 还真是哈哈哈
craftsmanship
9 天前
求求了 Java 就 Java 别带上其他语言了 削足适履真的难受
xiuming
9 天前
golang 是组合式编程
qweruiop
9 天前
@veike 刚才看了下,这个网站做的真好,就是文案有点 out 了,感觉是翻译的,如果有人能用现代中文美化一次就好了。
wogogoing
9 天前
@Ketteiron
[至于 Go 呢,package 是单例,sync.Once 可以实现延迟加载。]

啊?
mightybruce
9 天前
看了几眼,在 go 中用法错误,属于强行套用 OOP 在 go 上面
https://github.com/yuluo-yx/design-pattern/tree/main/struct-type/07_decorator
这个例子就是 go 语言用法错误

正确写法在这里
https://coolshell.cn/articles/17929.html
veike
9 天前
@qweruiop 是翻译的,还有其他各国语言。
Ketteiron
9 天前
@wogogoing #8 哪里有问题?
Go 保证一个 package 只会初始化一次,包内的变量是包级作用域的全局变量,全局唯一,这不就是天生的单例。
扩展阅读: https://stackoverflow.com/questions/1823286/singleton-in-go
`Just put your variables and functions at the package level.`
这能够解决 99%使用场景,如果无法解决,参考排名第一的回答。
darksword21
9 天前
应该是大脑被 java 造成了永久性损伤
sky3hao9
9 天前
大脑被 java 污染后, 再写别的语言, 容易抹黑人家
gowk
9 天前
看到前面几楼都在吐槽用设计模式污染 Go ,确实不能照搬,Go 有自己的惯用法( idioms ),好的代码不是设计模式堆砌出来的,而是解决实际问题、可读性强、易于维护的代码。
encounter2017
9 天前
只写 java 的是这样的,建议也多看看其他语言,所谓的设计模式,在现代的编程语言中,很多都内化成语法了,举几个例子:
策略模式:一等函数公民(js/ts),匿名函数 (c#), 类型类( scala )
构造者模式:case class (scala), record(jdk 17), data class(kotlin), dataclasses/pydantic (python )
visitor 模式: 代数数据类型 (rust), sealed trait + 模式匹配 (scala)
单例模式: 语法关键字支持( scala/kotlin ), 类本身就是 (ruby)
Decorator 模式:Decorator 注解(python)
encounter2017
9 天前
引用下 https://refactoringguru.cn/design-patterns 的一段话:

设计模式自其诞生之初似乎就饱受争议, 所以让我们来看看针对模式的最常见批评吧。

一种针对不完善编程语言的蹩脚解决方案
通常当所选编程语言或技术缺少必要的抽象功能时, 人们才需要设计模式。 在这种情况下, 模式是一种可为语言提供更优功能的蹩脚解决方案。

例如, 策略模式在绝大部分现代编程语言中可以简单地使用匿名 ( lambda ) 函数来实现。
kuanat
9 天前
设计模式是一种经验总结,属于应对特定问题的一般策略。实际上就算你一点设计模式不懂,一样能写出能用的代码,只是可能比较复杂容易出错,或者看起来没那么简洁易懂。当你反复遇到相同的问题时,很有可能自己重新发现并总结出某种设计模式。或者说你可能早就在用各种设计模式了,只是没有总结成特定的名词而已。

但所谓的设计模式毕竟是经验总结啊,也就是说它是有适用范围的。不能因为手里拿着设计模式的锤子,就看什么都是钉子。不同的编程语言差别很大,解决相同问题的经验是完全不同的,甚至在一种语言中的常见问题在另一种语言中甚至不存在。

举个例子,就拿参数传递来说,Java 因为不支持命名参数但支持重载,所以总结出了 builder 模式,而 Go 因为没有重载和构造函数,所以形成了函数式 Options 的习惯写法。非要 Go 用 builder 模式或者 Java 写函数式 Options 不是不行,只是没必要。

再比如楼上提到的装饰器模式,Java/C++ 这种常用是因为它们的 OOP 都是基于继承的,在不修改原始类的情况下动态增加新功能是比较复杂的,装饰器这个写法可以避免继承爆炸。换到 Go 里面正经人谁用装饰器啊? Go 的 OOP 是基于组合的,简简单单嵌入 struct 不就可以了。

当然面试八股确实喜欢考这些东西,但属实没必要把设计模式当作编程学习的目标。
yb2313
9 天前
写 java 写的
pengtao2001
9 天前
@Ketteiron 发现新大陆
midsolo
9 天前
设计模式是一套经验思想,只要语言实现了面向对象特性(封装、继承、多态),那么都可以使用设计模式。Java 只需要使用接口跟抽象类,把行为和对象隔离,保证高内聚低耦合。只要不需要直接依赖,那就引入中间层,你要什么设计模式都可以帮你抽。

一些菜鸡面试官自己都没理解,还喜欢问这些,如果你不按照他的认知去回答,他还觉得你在胡说八道,难崩。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1164961

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX