Coder scroll

Separation of concerns - ​Divide your application into distinct features with as little overlap in functionality as possible. The important factor is minimization of interaction points to achieve high cohesion and low coupling. However,  separating functionality at the wrong boundaries can result in high coupling and complexity between features even though the contained functionality within a feature does not significantly overlap.

Single Responsibility – ​Every object should have a single responsibility, and all its services should be narrowly aligned with that responsibility

Open/Closed Principle - ​should be open for extension, but closed for modification

Liskov Substitution - ​Subtypes must be substitutable for their base types

Interface Segregation - ​Clients should not be forced to depend on methods they do not use

Dependency Inversion - ​Abstractions should not depend on details. Details should depend on abstractions

Release Reuse Equivalency Principle (REP) ​- The granule of reuse is the granule of release. Users will be unwilling to use the element if they need or forced to upgrade every time author changes it.

Common Closure Principle (CCP) ​- Classes those changes together belong together. The more packages that change in any given release, the greater the work to rebuild, test and deploy the release. So they should be grouped together.

Common Reuse Principle (CRP) ​- Classes that are not used together should not be grouped together. A dependency upon a package is a dependency upon everything in the package. When a package changes, and its release number is bumped , all clients of that package must verify that they work with the new package even if nothing they used within package actually changed.

Acyclic Dependencies Principle (ADP) ​- The dependencies between packages must not form cycles.

Stable Dependencies Principle (SDP) ​- Depend in the direction of stability. A package with lots of incoming dependencies is very stable because it requires a great deal of work to reconcile any changes with all the dependent packages.

Stable Abstraction Principle (SAP) ​- Stable packages should be abstract packages. It’s just a restatement of the DIP. It states that the packages that are most dependent upon (i.e. stable) should also be most abstract.

Information Hiding ​- a design decision should be hidden from the rest of the system to prevent unintended coupling.

Don't Repeat Yourself - ​Every piece of knowledge must have a single, unambiguous representation in the system.

You Ain't Gonna Need It – ​Don’t waste resources on what you might need.

Keep It Simple, Stupid - ​Most systems work best if they are kept simple.

Golden Hammer - ​When you know only one tool, everything looks like a nail

Feature Creep – ​avoid overdesign

Death March – ​think before start coding

Duck Tape Coder – ​seems to work, so ship it

Iceberg Class – ​it’s cool to hide your code, keep principles at all levels

Spaghetti Code – ​avoid putting everything in one place

Calendar Coder – ​blindly following tips/code found

Reinventing The Wheel – ​search for solutions

Invent Square Wheel – adapt solutions to your case

Copy Paste Programming – ​‘we only need to add one thing’

Boy Scout Rule – ​Leave code better than you found it

Technical debt - the cost of taking shortcuts and making mistakes in your code. You could have gotten here through lack of testing, pushing code into production too soon, or not documenting every patch and issue.

Reverse Grind - is an accumulation of repetitive tasks you’ve postponed, and now you have to backtrack and complete what is now a large project. Had you stuck to the routine of doing these tasks in the moment, they would not be difficult to complete since you'd be the correct mindset. By letting them build up you have to be in a totally different state of mind, and repeated repetitive work like this can become tedious quickly.

Code gardening - “code maintenance” as editing source code to make non-functional changes, such as:fixing formatting,fixing whitespace,improving consistency, correcting typos,commenting,minor refactoring,removing dead code.Changes about improving code hygiene, tasks which are not normally scheduled or allocated.Either you fix it now (garden as you go, but commit your maintenance changes separately), or save it for later (do it all on  Weeding Day).

Design By Committee – ​avoid more meetings/design, than coding

Copy Folder Versioning – ​use Version Control Systems.

Association - ​is a relationship where all objects have their own lifecycle and there is no owner(no ownership between the objects and both have their own lifecycle). Both can create and delete independently.

Aggregation - ​is a specialised form of Association where all objects have their own lifecycle, but there is ownership and child objects can not belong to another parent object. We can think about it as a “has-a” relationship.

Composition - ​is again specialised form of Aggregation and we can call this as a “death” relationship. It is a strong type of Aggregation. Child object does not have its lifecycle and if parent object is deleted, all child objects will also be deleted.

High fan-in - a component is needed by many other components.

High fan-out
- a component depends on many other components.

Principle of Least Knowledge​(a.k.a Law of Demeter or LoD) - component or object should not know about internal details of other components or objects.

Minimize upfront design ​- Only design what is necessary. In some cases, you may require upfront comprehensive design and testing if the cost of development or a failure in the design is very high. In other cases, especially for agile development, you can avoid big design upfront (BDUF). If your application requirements are unclear, or if there is a possibility of the design evolving over time, avoid making a large design effort prematurely. This principle is sometimes known as YAGNI (You ain’t gonna need it).

Keep design patterns consistent within each layer ​- Within a logical layer, where possible, the design of components should be consistent for a particular operation. For example, if you choose to use the Table Data Gateway pattern to create an object that acts as a gateway to tables or views in a database, you should not include another pattern such as Repository, which uses a different paradigm for accessing data and initializing business entities. However, you may need to use different patterns for tasks in a layer that have a large variation in requirements, such as an application that contains business transaction and reporting functionality.

Composition over inheritance ​- wherever possible, use composition over inheritance when reusing functionality because inheritance increases the dependency between parent and child classes, thereby limiting the reuse of child classes. This also reduces the inheritance hierarchies, which can become very difficult to deal with.

Do not mix different types of components in the same logical layer ​- Start by identifying different areas of concern, and then group components associated with each area of concern into logical layers. For example, the UI layer should not contain business processing components, but instead should contain components used to handle user input and process user requests.

Keep the data format consistent within a layer or component​ - Mixing data formats will make the application more difficult to implement, extend, and maintain. Every time you need to convert data from one format to another, you are required to implement translation code to perform the operation and incur a processing overhead.

Do not overload the functionality of a component​ - For example, a UI processing component should not contain data access code or attempt to provide additional functionality. Overloaded components often have many functions and properties providing business functionality mixed with crosscutting functionality such as logging and exception handling. The result is a design that is very error prone and difficult to maintain. Applying the single responsibility and separation of concerns principles will help you to avoid this.
Define a clear contract for components ​- Components, modules, and functions should define a contract or interface specification that describes their usage and behavior clearly. The contract should describe how other components can access the internal functionality of the component, module, or function; and the behavior of that functionality in terms of pre-conditions, post-conditions, side effects, exceptions, performance characteristics, and other factors.

Design by contract​(DbC) - also known as contract programming, programming by contract and design-by- contract programming, is an approach for designing software. It prescribes that software designers should define formal, precise and verifiable interface specifications for software components, which extend the ordinary definition of abstract data types with preconditions, postconditions and invariants.

Code Contracts - A contract is an assertion in the code. If violated we consider that there must be a bug. Thrown exception is a behavior of your program, it is not a contract! A contract is not a behavior, it is an artefact around your code like a unit-test.

Command–query separation​(CQS) - every method should either be a command that performs an action, or a query that returns data to the caller, but not both. In other words, Asking a question should not change the answer.

Carter compass ​- you're on the right path, when you add new features and you delete code. Fewer lines = Fewer defects, technical debt, maintenance.

Cargo cult ​- coder uses software snippet without knowing how it works, “we’ve done things always this way, I don’t know why”

GRASP (General Responsibility Assignment Software Patterns/Principles) - consist of guidelines for assigning responsibility to classes and objects in object-oriented design. The different patterns and principles used in GRASP are: Controller, Creator, Indirection, Information Expert, High Cohesion, Low Coupling, Polymorphism, Protected Variations and
Pure Fabrication. These techniques have not been invented to create new ways of working, but to better document and standardize old, tried-and- tested programming principles in OOD.

TOGAF - a framework for enterprise architecture that provides an approach for designing, planning, implementing, and governing an enterprise information technology architecture. Based on four interrelated areas of specialization called architecture domains:
Business architecture defines the business strategy, governance, organization, and key business processes of the organization.
Applications architecture, a blueprint for the individual systems to be deployed, the interactions between the application systems, and their relationships to the core business processes of the organization with the frameworks for services to be exposed as business functions for integration.
Data architecture, describes the structure of an organization's logical and physical data assets and the associated data management resources.
Technical architecture, describes the hardware, software, and network infrastructure needed to support the deployment of core, mission-critical applications.

Extension points over features - it's better to enable new functionality by creating or augmenting an extension point (should be good at one thing) rather than adding the functionality as a core feature. Don't try to be a swiss army knife.

Problem decomposition - encapsulate aspects subject to change.

Cyclomatic Complexity – Measures the structural complexity of the code. It is created by calculating the number of different code paths in the flow of the program. A program that has complex control flow will require more tests to achieve good code coverage and will be less maintainable.

Lines of Code – Both physical and logical. A very high count might indicate that a type or method is trying to do too much work and should be split up. It might also indicate that the type or method might be hard to maintain.

Halstead Volume - Based on the numbers of operators and operands, complexity of calculations and objects your code do or work with.

Loop unrolling - transformation technique that attempts to optimize a program's execution speed at the expense of its binary size, which is an approach known as the space-time tradeoff. Done manually by the programmer or by an optimizing compiler. Can be re-written as a repeated sequence of similar independent statements.

Rubber duck debugging - explaining a programming problem to someone else, possibly even to someone who knows nothing about programming, and then hitting upon the solution in the process of explaining the problem.

Code three times - the code works is where you start. First PoC, Second is to make it work, Third is to make it better. Teaches how many ways are there to approach a problem.

Convention over configuration (coding by convention) - software design paradigm which essentially means a developer only needs to specify unconventional aspects of the application, gaining simplicity, and not necessarily losing flexibility.

Type Rank - some bits of code are extremely important to the system, with inbound and outbound dependencies. You can use Type Rank to create a release riskiness score. All you’d really need to do is have a build that tabulated which types had been modified and what their type rank was, and this would create a composite index of release riskiness. If it were higher than normal, you’d want to budget extra time and money for additional testing efforts and issue remediation strategies.

Crash on a non-critical path - make sure you aren’t generating unhandled exceptions in exception handling code.

No comments:

Post a Comment