开源日报 每天推荐一个 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/