開源日報 每天推薦一個 GitHub 優質開源項目和一篇精選英文科技或編程文章原文,堅持閱讀《開源日報》,保持每日學習的好習慣。
今日推薦開源項目:《心誠則靈 EagleEye》
今日推薦英文原文:《Clean Classes》

今日推薦開源項目:《心誠則靈 EagleEye》傳送門:GitHub鏈接
推薦理由:給這個項目一張照片,以及一些小小的情報,它就會從網路世界……里的臉書推特這些社交媒體上找出你想找的這個人。儘管社交網路上的情報大部分都不怎麼靠譜,目標人物到底是不是你想找的人還兩說(基於這一點,實在不推薦用於尋找心儀異性的社交賬號),但是最起碼這個人的信息一定和你給的情報有共同之處——興許網路世界裡真的存在著一個使用這個名字,上傳了這張照片的人也說不定。
今日推薦英文原文:《Clean Classes》作者:Dhananjay Trivedi
原文鏈接:https://medium.com/better-programming/clean-classes-43b46da37f39
推薦理由:在面向對象的編程中寫出乾淨的類

Clean Classes

Things that should be taught along with OOPS


The Clean Code series has been going really well! We』ve looked at how to write lines and blocks of code, how to write functions, and how to make the modular.

All these blocks of code combine together to form a higher level of code organization, which we refer to as Classes.
// Structuring a Standard Java Classpublic class ClassName {

  // Static constants  
    // Static variables  
    // Private constants  
    // Private instance variables 
    // Public functions()  
    // Private utilities functions()}
We want to keep our functions 『Private』 when we possibly can, but that doesn』t mean every time! We sometimes want our functions to be accessible through tests. We use these access modifiers to achieve encapsulation. Losing encapsulation in order to make your functions accessible by tests should always be the last option.

Two rules while writing classes

  1. Classes should be small
  2. Classes should be smaller than that!
Smaller is the primary rule when writing classes, while in functions we go for 「how small?」

We measure functions by the number of lines, while we measure classes by the number of responsibilities.

We should also be able to write a brief description of the class — in about 25 words, without using the words 「if」 「and」 「or」 「but」.

Let』s look at an example:
public class GodClass extends JFrame implements MetaDataUser{

    public Component getLastFocusedComponent()

    public void setLastFocused(Component lastFocused)

    public int getMajorVersionNumber()

    public int getMinorVersionNumber()

    public int getBuildNumber()
}
The class seems small but has diverse responsibilities: managing focus and getting the build number.

Remember the SRP — Single Responsibility Principle?

The class or module should have only one responsibility — one reason to change. SRP is one of the more important concepts in OO design. It』s also one of the simpler concepts to understand and adhere to.

Yet oddly, SRP is often the most abused class design principle because getting the software to work and making software clean are two very different activities.

Anyways, let』s break this class into two separate classes:
public class Version {

    public int getMajorVersionNumber()

    public int getMinorVersionNumber()

    public int getBuildNumber()
}
And the other…
public class FocusedComponent {
            public Component getLastFocusedComponent()
            public void setLastFocused(ComponentlastFocused)
}
There! That looks so clean and small! The problem is that too many of us think that we are done when the program works. We fail to switch to the other concerns: organization and cleanliness.

We move on to the next problem rather than going back and breaking the overstuffed classes into decoupled units with single responsibilities.

Do you want your tools organized into toolboxes with many small drawers, each containing well-defined and well-labeled components? Or do you want a few drawers that you just toss everything into?

Cohesion

There will be instance variables in our classes and there will be functions that will be manipulating these instance variables. The more variables a method manipulates, the more cohesive that method is to the class.

A class where each instance variable is being manipulated by each method is maximally cohesive. Hence, cohesion is just a measure of how much the variables and methods are logically related to each other.

When cohesion is high, it means that the methods and variables of the class are co-dependent and hang together as a logical whole.

The better the cohesion, the better the program design.
public class Stack {

    private int topOfStack = 0;    List<Integer> elements = new LinkedList<Integer>();

    public int size() { 
        return topOfStack;
    }

    public void push(int element) { 
        topOfStack++; 
        elements.add(element);
    }

    public int pop() throws PoppedWhenEmpty { if (topOfStack == 0)
        throw new PoppedWhenEmpty();
        int element = elements.get(--topOfStack); 
        elements.remove(topOfStack);
        return element;
    }
}
In this example, the push() and pop() both are mutating the two instance variables elements and topOfStack. Hence it's quite cohesive.

Maintaining cohesion requires breaking your class into a lot more smaller atomic classes. Whenever class loses cohesion, that』s a hint for you to split them.

There are multiple types of Cohesion.
  • Co-incidental cohesion — Unplanned, random which is an outcome of modularization of code. Since it's unplanned, it』s not acceptable as it can be confusing to the programmers.
  • Logical cohesion — When you plan and put logical related statements and instructions in one module.
  • Procedural cohesion — When elements of a module are put together to perform one task.
  • Communicational cohesion — When elements are grouped together which are executed sequentially and work on the same data.
  • Temporal cohesion — When elements are structured so that they are processed at a similar point of time, it is called temporal cohesion.
  • Sequential cohesion — When the output of one element serves as input to the next one, and they are structured together, it is called sequential cohesion.
  • Functional cohesion — When elements contribute to make a single well-defined function.

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