CodingTour
ARTS #78 | 设计模式的背后

Algorithm

本周选择的算法题是:Generate Parentheses

规则如下:

Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.

Example 1:

Input: n = 3
Output: ["((()))","(()())","(())()","()(())","()()()"]

Example 2:

Input: n = 1
Output: ["()"]

Constraints:

  • 1 <= n <= 8

Solution

class Solution:
    def generateParenthesis(self, n: int) -> List[str]:
        ans = []
        def backtrack(item: str, left: int, right: int):
            if len(item) == 2 * n:
                ans.append(item)
                return
            if left < n:
                backtrack(f"{item}(", left + 1, right)
            if right < left:
                backtrack(f"{item})", left, right + 1)
            pass
        backtrack("", 0, 0)
        return ans

Review

2 Most Powerful Ways to Remember Everything You Learn

这篇文章先简要介绍了人的记忆系统,然后引出了艾宾浩斯遗忘曲线,最后介绍了两种提高记忆效率的方式:

  • 间歇性的重复 - 市面上很多背英语的软件采用了这种方式,不断的回顾已学习到的知识来提高大脑对它的重要性评级
  • 50/50 法则 - 把学习周期分为两部分,50%的时间用来学习,50%的时间用来分享或教授给别人

这两种方式都是帮助大脑对知识进行分类,现代社会的信息量太大了,大脑必须过滤掉很多信息以释放更多的内存给重要的部分,这意味着大脑要处理的数据量比以往更多,如果我们想留下真正重要的东西,必须得掌握一定的训练技巧。

Tip

推荐一个有趣的打卡社区:CheckiO,相比 LeetCode:

  • 游戏化
  • 问题类型更丰富
  • 不限制解题方式
  • 提示极具引导性:
  • 可以通过 Review 别人的代码找到一些骚操作

目前支持 Python 和 TypeScript 这两种语言。

Share

大家是否有过和其他人关于某个场景该用哪个设计模式的争论?

“我更倾向于用 MVVM”

“这个场景用 VIPER 更合适”

“MVC 就足够了”

“…”

这类讨论很难有一个完美的结束,这类讨论也永远不会停止。

我们常在一些场合听到别人用这样的分享开场白:

“我们这个系统采用了XXX设计模式”

“它采用XXX架构”

似乎在系统初始阶段就做了很清晰、完备的设计,并沿用至今,其实这是一个很大的误区,程序本身也是有生命力的,它会不断演进,这意味着很难在初始阶段就知道什么模式会适合你的场景,同时如果你对模式本身太过于关注,可能会陷入模式的陷阱中:我的代码一定要遵守XXX模式,哪怕和现有的场景有点不贴合了。

那要如何避免这些问题呢?

每个模式都有自己的价值,它们都是为某种常见的场景提供了通用的解决方案,虽然不同,但是它们背后的原则是一致的,即:

  • 模块化
  • 可重用性
  • 易读
  • 易修改

我们只需要在代码上应用这些原则,模式就会自然体现。我们不用太关注模式本身,因为模式热度会降低,而原则的生命力会很久;模块化,尽可能编写可重用的代码,维护合适的文档,就足以让我们写出出色的代码。

此外,真正理解代码是给人读的这一点很重要,不需要很 fancy,因为:

Any fool can write code that a computer can understand. Good programmers write code that humans can understand.

Martin Fowler

当然,如果你的代码既 fancy 也很容易理解,你就很棒。

最后总结一下,我们并不是说设计模式没用,而是希望能更进一步,了解「Why」,而不是只停留在「What」,真正理解你所使用的模式背后的原则,用好的编程设计原则去发现模式,因为原则才是每一个模式背后的基础。