Tuesday, January 16, 2018

Better Code



https://blog.csdn.net/xiedongsheng/article/details/79201795
  1. 大函数,超过500行,甚至超过1000行;
  2. 大量的hard coding;
  3. if和else if中有明显的条件关联性;
  4. 注释和代码逻辑不符合,函数名与功能不符合;
  5. 命名英文拼音混杂,不少英文拼写错误;
比如说写代码文档,最重要的一点,不是什么格式规范,而是要说人话,解释清楚你做的事情,不要解释代码,否则文档本身就不具有可读性。
不要为了写注释而写,与其三心二意的写一堆注释,不如写几行足够清晰的程序。
  1. 不要重复发明轮子,将公共的方法和函数抽出来做成公共库。投入一定的时间寻找和比较开源的解决方案,而非什么事情都自己实现。
  2. 投入跟多的时间在接口的定义和审核上,一个差接口的危害性超过 500 行烂代码。
  3. 请部门里更有经验的工程师帮助新人修改代码,相互工程师之间,相互抽查代码,这件事的好处不言而喻。虽然投入更多的时间,但是从整体效率的角度来讲,提高代码的可维护性就节省了大量的修改,重构代码的时间,可谓磨刀不误砍柴工。
  4. 要求工程师对自己的代码写单元测试。这就使得程序员有机会从使用者的角度审视和检测自己的代码,这样不但能提高代码的易用性和正确性,而且在代码发生改变的时候,程序员可以确保不会破坏引用此段代码的其他模块或项目。
  5. 从个人角度看,提高代码维护性,最直接的方式就是从好的代码Github上的代码库中学习,多看多总结。
  6. 最后一点,也是我一直要求团队的一点,团队中的每个人都要有大局观意识,埋头苦干的前提是要了解全局,每位工程师都应该知道自己的东西在整个项目构架中的位置和他工作的意义。
http://letstalkaboutjava.blogspot.com/2016/02/constructor-or-setter.html
Why do we have so many constructors? Because some dependencies are optional, their presence depends on external conditions.
what’s the purpose of the constructor?

We should create an object in a valid state. We should not allow to create an instance if there is something more that hasto be done to make an object usable. That’s why all required dependencies should be placed in a constructor.
On the other hand, we should place in the constructor only the required dependencies. Constructor is not a place for anything optional. If something is optional, this means we don’t need it to create a valid object. 

If we would like to use other dependencies that are nice to have we should inject them in different way. And this is where setters come into play. We are not forced to invoke setter method. We may have a need, but this is not required. You should use setters when dependency is an option.

From the first moment you know what is required and what just might be used.
Well, we will not avoid those methods. Or to be more precise - we need their functionality. There is a need to let the customer enable the functionality. In a given example mutators needs to stay because they’re needed. However, we can always make the code better. More domain-related. How? We just need to show this relation with the domain:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class SomeHandler {
   public SomeHandler(Repository repository, Trigger trigger) {
       // some code
   }
   public void enable(SnapshotTaker snapshotTaker) {
       // some code
   }
   public void enable(Notifier notifier) {
       // some code
   }
   public void handle(SomeEvent event) {
       // some code
   }
}
remember to name a method in a way that will show domain connotation.

Too many options

Sometimes too many options also pose a problem. It can be a sign that you’re violating Single Responsibility Principle
If there are too many options it might mean that there are too many responsibilities and it is worth re-thinking your current solution. 
Be very careful whenever adding another optional part into the code of the class. Maybe this class is doing too much?

You should know now that you ought to place only required dependencies in your constructors . Any optional dependencies require other well-named methods.
http://letstalkaboutjava.blogspot.com/2016/02/methods-name-change-lot.html
To make my thinking clear, I don’t have a problem with mutator methods, I just don’t like all of those setX/getX methods. Why? I believe that each method is about behavior and it name should tell something about this behavior. Setters tell us nothing about behaviour and make implementation details leaking.

public void enable(SnapshotTaker snapshotTaker) {
   // some code
}
public void enable(Notifier notifier) {
   // some code
}

But with different name we know what’s the purpose of those methods. We didn’t create them to set a field, we introduced them to make it possible to enable some optional functionality. 
The same functionality with different name gives us more valuable information. Explains the Why, not How.
https://dzone.com/articles/silly-code-can-we-try-to-do-a-bit-better-in-2018
Example #3: Hard-Coding in a Sea of Constants
if (type == TYPE.ACCOUNT) {
    // handle account-related tasks
} else if (type == TYPE.CONTACT || type == "customer") {
    // handle contact or customer tasks
}
Rule of thumb: Follow the established pattern, even if it means taking a couple extra steps to complete the task.

Example #5: Querying the World When You Only Need a Small Village

When introducing new program code as a part of a feature, I asked the team lead how I would gain access to the data I was developing. I noticed that I was going to use the same API call that was used in several other aspects of the application. When I called the API and reviewed the source data, I noticed the size of the payload that was returned. It was huge!
What was worse is that the expectation is that I would POST this payload back to the API, even if I only modified a few of the objects in the payload. When I viewed this design from a production-support perspective, I could not imagine the impact of performance and save conflicts that could occur with this model once deployed to a large user base.
Rule of thumb: Try to keep your payloads focused on meeting the needs of functionality being addressed.

Maybe some of you at this moment recognize an anti-pattern that is known as anemic domain model?
refactoring.started();
refactoring.accepted();
refactoring.applied();
I believe that some of you at this moment thought “Wait, but know I will have three methods that underneath will do exactly the same?”
The answer is yes, all of those method will set the value of the state attribute. But does it really matter? Are we interested in the attribute value? Are we interested in the attribute at all? No, we just want to be sure that refactoring was started/accepted/applied. We don’t care about the way how it was implemented at all.
Thanks to such design we may changing implementation in any way we want as long as the contract conditions are met. Information about implementation are unknown at this moment. We know what we have to know and nothing except this. The functionality that is using the object is not so tightly coupled with its implementation details anymore.

Labels

Review (572) System Design (334) System Design - Review (198) Java (189) Coding (75) Interview-System Design (65) Interview (63) Book Notes (59) Coding - Review (59) to-do (45) Linux (43) Knowledge (39) Interview-Java (35) Knowledge - Review (32) Database (31) Design Patterns (31) Big Data (29) Product Architecture (28) MultiThread (27) Soft Skills (27) Concurrency (26) Cracking Code Interview (26) Miscs (25) Distributed (24) OOD Design (24) Google (23) Career (22) Interview - Review (21) Java - Code (21) Operating System (21) Interview Q&A (20) System Design - Practice (20) Tips (19) Algorithm (17) Company - Facebook (17) Security (17) How to Ace Interview (16) Brain Teaser (14) Linux - Shell (14) Redis (14) Testing (14) Tools (14) Code Quality (13) Search (13) Spark (13) Spring (13) Company - LinkedIn (12) How to (12) Interview-Database (12) Interview-Operating System (12) Solr (12) Architecture Principles (11) Resource (10) Amazon (9) Cache (9) Git (9) Interview - MultiThread (9) Scalability (9) Trouble Shooting (9) Web Dev (9) Architecture Model (8) Better Programmer (8) Cassandra (8) Company - Uber (8) Java67 (8) Math (8) OO Design principles (8) SOLID (8) Design (7) Interview Corner (7) JVM (7) Java Basics (7) Kafka (7) Mac (7) Machine Learning (7) NoSQL (7) C++ (6) Chrome (6) File System (6) Highscalability (6) How to Better (6) Network (6) Restful (6) CareerCup (5) Code Review (5) Hash (5) How to Interview (5) JDK Source Code (5) JavaScript (5) Leetcode (5) Must Known (5) Python (5)

Popular Posts