# Good Programming Practices * Use Meaningful Names and Avoid Made-Up Acronyms ```C# // Avoid this label1.text = dog.name label2.text = dog.breed label3.text = dog.int_temp label4.text = dog.breed.int_fact // Do this name_label.text = dog.name breed_label.text = dog.breed internal_temperature_label.text = dog.internal_temperature interesting_fact_label.text = dog.breed.interesting_fact ``` * Follow the programming language / project Conventions * ### Functions * If something is repeated twice anywhere in code make it a function. * Keep Functions Short and to the Point. How short? around 20-25 lines or less. * The function should fit entirely on your screen so that you don’t have to scroll to read it completely, if you have a large screen make the function fit 1/2 or 1/3 of your screen. * Don't just break a large function in smaller ones, each individual small function should make sense in isolation. * The function should do what the name PROMISED it would do. * Update Member Variables Explicitly. If the function is part of business domain entity it's ok to update it's variables BUT if it is not then *return the changes* and *assign the values explicitly* to the member variable. * always try using pure functions ```javascript // this function doesnt mutate passed array, // instead returns sorted array as a new array function sortArray(arr, compareFunction = null) { return [...arr].sort(compareFunction) } ``` * Avoid Duplication. * Before writing a new function to do something check if a function for that thing already exits. * Keep common utlitiy function in a common project/class/file. eg. function for getting ip address for all interfaces OR function to encode a string to base64. * If two or more functions do similar things with some common behaviour refactor them into a common function (but follow above function rules). * Avoid Hard-Coded Strings and Magic Numbers. * Every string should be a reference to a string resource, or a constant. * Store common strings, enums, numbers used throughout project in their common files. * Instead of using magic numbers make them constants or enums. eg. ```C# const float PI = 3.14159; const string SuccessfullyCompletedMessage = "Successfully Completed"; // DO NOT DO THIS int connectionStatus = 0; // 0 is disconnected, 1 is connected // DO THIS enum ConnectionStatus { Connected, Disconnected } ``` - Define custom types for value objects. eg. for e-mail, geolocation (lat-long). ```C# class Email { Public string EmailId { get; private set; } Email(string emailId) { VerifyEmailFormatCorrect(emailId); EmailId = emailId; } private VerifyEmailFormatCorrect(string emailId) { // verify if (!verified) { throw EmailFormatException(); } } public override bool Equals(object obj) { // check return result; } public static bool operator !=(Email money1, Email money2) { // check return result; } public static bool operator ==(Email email1, Email email2) { // compare return result; } } ``` - Validate and check input/data from Unreliable Sources such as users or third party api's. - Always Write Braces Around Single Line Blocks ## SOLID ### 1. Single-Responsibilty Principle > Each and every class in your project should have one, and only one responsibility. example: ```C# # BAD class Logger { string LogType { get; set; } public Logger(string logType) { LogType = logType; } public log(string message) { if ( LogType == "console" ) { Conosle.WriteLine(message); } else if( LogType == "file" ) { File.write("logs.txt", message); } } } # GOOD interface ILogger { public void LogMessage(string message); } class EventTracker { ILogger Logger { get; set; } public EventTracker(ILogger logger) { Logger = logger; } } class ConsoleLogger : ILogger { public void LogMessage(string message) { Console.WriteLine(message); } } class FileLogger : ILogger { public void LogMessage(string message) { File.write("logs.txt", message); } } ``` ### 2. Open-Closed Principle > Entities in your software system should be open for extension, but closed for modification. ### 3. Liskov Substitution Principle > Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it. ### 4. Interface Segregation Principle > Clients should not have to implement interfaces that they don’t use. ### 5. Dependency Inversion Principle > High level modules should not depend on lower level modules. Both should depend on abstractions. Abstractions should not depend on details. Details should depend on abstractions. - ## General - Do peer code reviewing - Refactor you written code daily. And/or assign a day in week to sit down and refactor all your weeks code. - If you are making changes to some existing code Or adding - ## Links to articles - * [good programming practices](https://x-team.com/blog/good-programming-practices-blog-post-wip/) * [few simple rules to write good code](https://hackernoon.com/few-simple-rules-for-good-coding-my-15-years-experience-96cb29d4acd9) * [The Single Responsibility Principle with C# Examples](https://www.intertech.com/Blog/the-single-responsibility-principle-with-c-examples/) * [How to write SOLID code that doesn’t suck](https://medium.com/web-engineering-vox/how-to-write-solid-code-that-doesnt-suck-2a3416623d48) * [solid principles in real world](http://blog.gauffin.org/2012/05/solid-principles-with-real-world-examples/) * [how to write solid code that doesnt suck](https://medium.com/web-engineering-vox/how-to-write-solid-code-that-doesnt-suck-2a3416623d48) Some <span style="color:blue">blue text</span>.