Method Conventions Definition:
Guidelines for Method Code Block Structure and Proper Signature Creation including Parameter Standards using Dependency Inversion Practices
Method Conventions Justification:
All behavior actions are managed by Action Methods. It is the most valued of the Class Elements as all responsibilities are carried out in Class Action Methods.
Code standards for this very important Class member are vital to conveying a clear intent of the underlying Method Software Entity.
Method Conventions Standards:
Methods are Class members that are called upon to perform some action. They are behaviour Class members. They consume dependencies and perform tasks.
A Method may act as a traditional programming Function by acting on known objects and return no value object. This is a Void action.
Methods can also act as behavior Class Members and return known C# types.
A Method defines a Single Responsibility Action. It does not manage or create any dependencies to be consumed. It consumes dependencies to fulfil its contractual obligation to the calling Software Entity.
Any internal algorithm, logic or conditional that does not go directly to the intent of the Method responsibility needs to be analysed as a “One and Only One” Class level usage dependency or a candidate for code reuse.
Code reuse Methods become Public Methods and refactored into common Helper Classes. Class-centric Methods are marked Private and reside in the Helpers region for Class consumption.
This complies with the Open / Closed Principle, when applied to Methods, as it allows the dependency to be “Open” for future extension but “Closed” to the parent Method for modification.
Generally a Method should not exceed 20 lines of code. You can almost always find a refactoring opportunity in long Class Methods. Helper Methods should always be Static as they are a singleton by definition.
Extension Methods that extend a common Class such as String or DateTime can be used to abstract away the location and type of the containing Class.
Extension methods use the “this” keyword before the existing C# type to extend. This gives the Developer intellisense access to a containing method without having to know where the containing Class exists.
It is represented by a tiny icon on the method name in intellisense.
LINQ uses numerous extension methods to extend IEnumerable.
If a Method can or should be changed by an inheritance hierarchy then the virtual keyword should be used.
The virtual keyword with the override keyword should be used by any type that is a candidate for a testing mock object as mocking frameworks creates mocks as derived objects.
Method Hiding in C# with the new keyword in a derived Class should NEVER be used. This violates the Liskov Substitution Principle and blurs the OOP concept of an “Is A” relationship to its Base Class.
Method Best Practices:
Enforce the Method’s Single Responsibly by refactoring into Private Class Public Helper Methods all code that performs dependency tasks for the Single Responsibility of the Method.
This aids in a better understanding of “What” the Method is doing by not introducing “Code Noise” that has nothing to do with the intent of the Single Responsibility.
Create short Helper Methods for Method Dependencies to help the Just-In-Time (JIT) compiler at runtime to more efficiently supporting the Common Language Run-time (CLR).
The JIT can use “Enregistering” for small blocks of code, as signatures and not the implementation code, in memory as Single Blocks of Managed Heap Memory.
Tens of Thousands of Registered Signatures can be accessed through Stack Pointers and not consume Managed Heap Memory until the Methods are actually required.
Use Constructor State DTOs to encapsulate long Parameter collections.
Often times these objects can be used more than once and should be in an Aggregate DTO folder within the Assembly structure. This will allow for reuse of these objects.
These DTOs are called Parameter State Classes.
If a Parameter State Class is only used in the containing Class this is one of the few justifications for a Nested Class.
Its Access Modifier will always be Private.
If it is later determined that it is useful in another type it should be moved to an Aggregate DTO folder for reuse.
Comply with the Dependency Inversion Principle to pass instantiated Types as “new ups” or IOC resolutions to lower level modules as dependencies in the Constructor.
These Types can be empty objects or fully initialized.
This goes to clarity of the required Dependencies of the higher level Software Entities.
This also allows for Type replacement at the highest level of abstraction during future Change Requests and Refactoring activities.
Types at the top section of the Class aids in understanding of the required Dependencies consumed within the Class
Use C# Types managed by an Inversion of Control (IOC) container such as Unity to manage the lifetime of the instantiated Type whenever possible.
Use the Object initializer when you “New Up” a Type without an IOC that has known Property values.
Initializers aids in understanding the intent of the underlying Type by encapsulating Property values and not extending the initialization process into multiple lines of code.
Private Method variables should be created only if required more than one time.
If a variable is created and used only on the next line it is a “Temp Variable”.
Temp variables are used during the Debug stage of creating the GREEN TDD tests
Remove Temp Variables in the YELLOW Refactoring Stage of TDD
Temp Variables should NEVER be used in a Production environment.
Variables that are only used once engages the Garbage Collector needlessly.
Temp Variables are Unnecessary Resource Hogs
Copy the code that is used to by the Temp Variable and paste it where the Temp Variable is being used only once.
Use the “Find” feature in Visual Studio to validate that all private variables are required.
Select the variable and enter Cntrl+F to highlight all usages.
Sometimes you think a variable is used only once but it is actually used more than one time
Use “Method Chaining” for simple method returns to help prevent objects being created that are immediately Garbage collected as Temp Variables.
ReSharper will help with Return possibilities
Use Method Chaining only when it does not blur the intent of the underlying Method actions.
Methods are the Most Prolific Software Entity in Modern Programming
It is vital that these Method Practices, Principles and Standards be implemented.
Over 90% of “Code Smells”, bad or questionable code, resides if “Fat Methods” that violate the Method Single Responsibility.
The Top Standards that will Reduce Code Smell Percentage:
Identifying the Single Responsibility for the Return Type of the underlying method
Complete understanding of what Dependencies should be abstracted from the code block and replaced with Private or Public Helper Methods
Method Chaining become possible when the Dependencies are created outside the underlying Method. This “Fluent” flow of actions clearly defines the Single Responsibility of the Method and prevents “Method Bloating“
Private Helper Methods should be the only Class usages of the Regions Statement. Regions can be used to hide Single Responsibility Principle violations
Encapsulate all Private Helper Methods inside of a Single Region Section Block
Organizational Child Helper Regions, when required, within the Helper Region Section. This will help to prevent Class clutter while organizing the Method Dependencies in an organized fashion.
Methods Manage All Application Behavior …
… You Manage the Code Behavior of Methods