Coding Best Practices Part 1 (Naming Conventions & Class Designing Principles)
Mohit Rajput Apr 30 '17
In my last article IMPORTANCE OF WRITING CLEAN CODE, you realized the importance of creating a beautiful piece of code. You learned some techniques to optimize the source code. In this article, I will explain how to write beautiful, scalable, maintainable and readable code which will be cost effective in the agile development. These rules are not “forced to follow” but remember-
“You can but you should not”
This means, you can write code in any manner, but remember what you should follow and what not. These best practices will not just improve readability of your code; you will learn to create quality software. The topics can be broadly divided into two categories; one is naming convention and second is the best practices to design a class.
1. Naming Conventions-
Avoid ambiguous and small names which are hard to understand. Names should be descriptive such that it should tell what it is for. Following are some rules for naming conventions in Java. However, these rules are applied to other languages i.e. C++, PHP etc. Every language has its own naming convention-
a. Class- A class name must start with the capital letter then it should follow camel-case i.e. the first letter of every word in the class name would be capital. There is no need of underscore. It should be a noun. e.g.-
Wrong names- student, Inkjet_printer, Bookinghistory
Correct names- Student, InkjetPrinter, BookingHistory
b. Variable- The rules for the variable name are same as the class except for one change. The variable should start with a small letter. e.g-
Wrong names- Student, Inkjet_printer, Bookinghistory
Correct names- student, inkjetPrinter, bookingHistory
c. Method- The rules for method name are same as the variable. It should start with a small letter; it should be camel-case and for words’ separation, make the first letter of next word capital. It should be a verb. A method should do what its name says i.e. if the method name is “getExpensesHistory()”, it must return the object of “Expense” list. If you are making its return type void then it’s not doing the right purpose according to its name. e.g.-
Wrong names- void getExpensesHistory(), int setMyAge()
Correct names- List getExpensesHistory(), void setMyAge(int age)
d. Constants- A constant must be upper case. Unlike class, variable and method, its words should be separated by underscores.
Wrong names- minRegistrationAge, MINREGISTRATIONAGE
Correct names- MIN_REGISTRATION_AGE
e. Interface- All rules for interface name are same as the class. It should be an adjective instead of the noun. It would be good if you start your interface name with the capital I, so it would be easy for searching it in a large codebase.
Wrong names- onClick_listener, OnClick_listener, onClick
Correct names- OnClickListener, IOnClickListener
f. Package- All letters of the package should be lower. A project must have the package name of up to three levels. If your company’s domain is XYZ.com and project name is ABC, then package name should be “com.xyz.abc”. Then you can create multiple packages inside abc for different things i.e. beans, database, util.
2. Class Design (SOLID principle) -
Classes are the bricks which are going to make a strong building. If these building blocks are not robust, your building may be destroyed soon. For a powerful class designing, there are principles called SOLID which has five principles-
a. Single Responsibility Principle (SRP) - A class should have one and only one responsibility. All its methods should work together to achieve a single goal. E.g.- If you are fetching location of a user, it should only do location related jobs. If it’s a model class, it should represent only one entity.
b. Open Closed Principle (OCP) - A class must be open for extension but closed for modification. This means you should write a class in such a way that if your fellow developer wants to use your class, he should be able to inherit it. If any extra feature is required with existing, he should be able to override that method and write code for the extension. There should not be any need of modification in existing code. e.g. – Have a look at the Spring framework in java. You cannot modify its logic but you can create application flow by extending its classes.
c. Liskov’s Substitution Principle (LSP) - It can be said that the variation of OCP. This principle says "Derived types must be completely substitutable for their base types". This means if a fellow developer creates a class by extending your class, it should not break the application or changing its behavior. e.g.-
Square ‘is a’ Rectangle with specialization. It has same length and width. You can create Square by extending Rectangle which is looking logical. But if you set the width in the square, it sets height too. If you set height, it sets width too. The fellow developer can’t see this behavior and he will expect that if he is setting the only width, then there is no change in height. This breaks the Liskov’s principle.
d. Interface Segregation Principle (ISP)- According to this principle, you should design an interface in such a way that the fellow developer should not need to implement unnecessary methods. The principle says, "Clients should not be forced to implement unnecessary methods which they will not use". e.g.-
There is an interface called “IShape” with two methods- getArea() and getWidth(). If you are creating a Circle by implementing this interface, you will implement getArea() method but you will be forced to implement getWidth() also even if there is nothing like width in a circle. You have to implement it and leave it blank. You can create a new interface called “IPolygon” by extending “IShape”. IShape will have only one method getArea() and IPolygon can have the getWidth() method.
e. Dependency Inversion Principle (DIP) - This principle encourages you to write code that depends upon abstractions rather than upon concrete details. The principle defined by Robert C. Martin in his book Agile Software Development, Principles, Patterns and Practices says that-
(i). High-level modules should not depend on low-level modules. Both should depend on abstractions.
(ii). Abstractions should not depend upon details. Details should depend upon abstractions.
For example- If you are paying at a shop with a credit card, you should not be bothered by whether it is Visa or MasterCard. The high-level credit card should not have any effect on the effects of low-level specialized cards. You can swipe any card in the machine.
These two techniques are the basic techniques to write the professional code. The article may look like more of Java, C++ & PHP specific. The naming convention is based on Java naming convention. Rules for the different languages are different. But basic rules are same for all OOPS languages. In next article, I will come with object declaration techniques. Till then learn and implement these rules. I would love to see your thoughts on the comment.
Also, have a look at the case study of mobile junk cleaning app mDoctor developed by me-