開源日報 每天推薦一個 GitHub 優質開源項目和一篇精選英文科技或編程文章原文,堅持閱讀《開源日報》,保持每日學習的好習慣。
今日推薦開源項目:《遁入黑暗 halfmoon》
今日推薦英文原文:《When DRY Doesn』t Work, Go WET》

今日推薦開源項目:《遁入黑暗 halfmoon》傳送門:項目鏈接
推薦理由:這是一個類似於 BootStrap 的框架項目——通過 CSS 提供了各種常用頁面組件,同時提供 JS 庫作為附贈品,甚至連類名這些都和 BootStrap 差不到哪去,如果有過 BootStrap 使用經驗的話很快就能上手。這個項目最大的亮點在於提供了簡便的黑暗模式,只需簡單的調用附加 JS 庫中的一個函數,就能使頁面自動切換到黑暗模式,從而更滿足夜晚熄燈之後的使用需要。
今日推薦英文原文:《When DRY Doesn』t Work, Go WET》作者:? Nick Bull JS
原文鏈接:https://medium.com/better-programming/when-dry-doesnt-work-go-wet-6befda0444bf
推薦理由:重複不可恥而且有用

When DRY Doesn』t Work, Go WET

It』s okay if you repeat yourself

I』ve seen this mistake many times, and I』ve made it myself. When you first read about the DRY programming concept, you probably misunderstood it.

What was going on in your head was this:

Wikipedia: DRY stands for not repeating the same code twice.
You: Hmm, ok I』ll replace all my duplications with abstraction.

And it seems like a good solution, but it』s not. Your abstraction is often wrong.

Here is why:
  1. You see duplication.
  2. You extract duplication into a new abstraction (method, class).
  3. You replace the duplication with the new abstraction.
  4. You think your code is perfect.
  5. Time passes.
  6. The product manager has new requirements. Your abstraction is almost perfect for them.
  7. You start to implement the new requirements.
  8. And here』s the little but:
  9. Your abstraction is almost perfect. Why? The new requirements affect only 95% of the old code you extracted into abstraction. The other 5% is not affected. And instead of creating a new abstraction with 95% copied code from the current one, you decide to change the code of your abstraction.
  10. You add a conditional statement, if..else for example, and pass a parameter, so your abstraction can perform different actions for different decisions.
  11. Now your abstraction behaves differently for different cases.
  12. Another new requirement arrives. Another additional parameter. Another new conditional. (Loop until code becomes very difficult to understand and maintain.)
  13. Congrats, you』ve created a wrong abstraction.
The code no longer represents a single, common abstraction. It becomes a condition-laden procedure. It』s hard to understand and easy to break. Adding new features is incredibly hard and every new feature complicates the code even more.

It』s an infinite loop.

So what to do?

Write Everything Twice.

WET

WET (Write Everything Twice) is the opposite concept to DRY. When you start to develop a new system you don』t know all the future requirements. So don』t rush into abstractions.

You need to remember: Duplication is far cheaper than the wrong abstraction.

For example, you are building a web app and don』t have a UI design for all pages right now. But you also have many buttons, and they』re similar on every page. You decide to move them to a component called Button and reuse it on every page. Seems logical.

「Hey, hey!」 the new page design came from the product manager. You look at it and find a new, fancy button at the bottom of the page.

It looks like the old buttons, but it has this 「one little thing.」 To implement it, you need to rewrite 10% of your Button component, and add conditional statements and new parameters.

Now you have a dilemma:
  • Change Button. Rewrite 10% of the abstraction code (add logical conditions to support new fancy button logic).
  • Create two abstractions: FancyButton and Button. Copy 90% code from Button to FancyButton.
I know you want to choose the first option. You think that you can handle it. You』re not going to build the wrong abstraction.

But the sad truth is, you will (except if you are an experienced programmer and know what you』re doing).

Copy that code. Don't be afraid.

After a while, you will know what your buttons will look like in the future. Then you can analyze the current codebase, find duplicated code in the button components, and move them to the good abstraction.

If It』s Too Late

If you find that it』s too late to deal with a wrong abstraction, the fastest way to move forward is back.

Do the following:
  1. Move the abstracted code back.
  2. Delete the unused parameter that』s passed to the abstraction to perform different actions for different decisions.
  3. Delete unused logic.
This removes the abstraction and conditional statements for each caller.

In the End…

If you find yourself passing parameters and adding conditional statements through shared code, your abstraction is wrong.

Prefer duplication over the wrong abstraction.

Thanks for reading!
下載開源日報APP:https://openingsource.org/2579/
加入我們:https://openingsource.org/about/join/
關注我們:https://openingsource.org/about/love/