- Notifications
You must be signed in to change notification settings - Fork0
OpenSourceLearningRepos/programming-principles
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Every programmer benefits from understanding programming principles and designpatterns. This overview is a reference for myself, and maybe it is of help toyou during design, discussion, or review. The list is incomplete, and sometimestrade-offs need to be made between conflicting principles. However, higherranked principles usually beat lower ranked ones.
The list was inspired byThe Principles of Good Programming.I've added a bit more reasoning, details, and links to further resources.Let me know if youhave any feedback or suggestions for improvement!
- KISS
- YAGNI
- Do The Simplest Thing That Could Possibly Work
- Separation of Concerns
- Keep things DRY
- Code For The Maintainer
- Avoid Premature Optimization
- Boy-Scout Rule
- Minimise Coupling
- Law of Demeter
- Composition Over Inheritance
- Orthogonality
- Robustness Principle
- Inversion of Control
- Maximise Cohesion
- Liskov Substitution Principle
- Open/Closed Principle
- Single Responsibility Principle
- Hide Implementation Details
- Curly's Law
- Encapsulate What Changes
- Interface Segregation Principle
- Command Query Separation
- SOLID
Keep It Simple, Stupid: most systems work best if they are kept simplerather than made complex.
Why
- Less code takes less time to write, has less bugs, and is easier to modify.
- Simplicity is the ultimate sophistication.
- It seems that perfection is reached not when there is nothing left to add, butwhen there is nothing left to take away.
Resources
You Aren't Gonna Need It: don't implement something until it is necessary.
Why
- Any work that's only used for a feature that's needed tomorrow, means losingeffort from features that need to be done for the current iteration.
- It leads to code bloat; the software becomes larger and more complicated.
How
- Always implement things when you actually need them, never when you justforesee that you need them.
Resources
Why
- Real progress against the real problem is maximized if we just work on whatthe problem really is.
How
- Ask yourself: "What is the simplest thing that could possibly work?"
Resources
Separation of concerns is a design principle for separating a computer programinto distinct sections, such that each section addresses a separate concern. Forexample, the business logic and the user interface of an application areseparate concerns. Changing the user interface should not require changes to thebusiness logic and vice versa.
QuotingEdsger W. Dijkstra(1974):
It is what I sometimes have called "the separation of concerns", which, evenif not perfectly possible, is yet the only available technique for effectiveordering of one's thoughts, that I know of. This is what I mean by "focusingone's attention upon some aspect": it does not mean ignoring the otheraspects, it is just doing justice to the fact that from this aspect's point ofview, the other is irrelevant.
Why
- Simplify development and maintenance of software applications.
- When concerns are well-separated, individual sections can be reused, as wellas developed and updated independently.
How
- Break program functionality into separate modules that overlap as little aspossible.
Resources
Don't Repeat Yourself: Every piece of knowledge must have a single,unambiguous, authoritative representation within a system.
Each significant piece of functionality in a program should be implemented injust one place in the source code. Where similar functions are carried out bydistinct pieces of code, it is generally beneficial to combine them into one byabstracting out the varying parts.
Why
- Duplication (inadvertent or purposeful duplication) can lead to maintenancenightmares, poor factoring, and logical contradictions.
- A modification of any single element of a system does not require a change inother logically unrelated elements.
- Additionally, elements that are logically related all change predictably anduniformly, and are thus kept in sync.
How
- Put business rules, long expressions, if statements, math formulas, metadata,etc. in only one place.
- Identify the single, definitive source of every piece of knowledge used inyour system, and then use that source to generate applicable instances of thatknowledge (code, documentation, tests, etc).
- Apply theRule of three.
Resources
Related
- Abstraction principle
- Once And Only Once is a subset of DRY(also referred to as the goal of refactoring).
- Single Source of Truth
- A violation of DRY isWET(Write Everything Twice)
- Be careful with the code metric "duplicated lines"
Why
- Maintenance is by far the most expensive phase of any project.
How
- Be the maintainer.
- Always code as if the person who ends up maintaining your code is a violentpsychopath who knows where you live.
- Always code and comment in such a way that if someone a few notches juniorpicks up the code, they will take pleasure in reading and learning from it.
- Don't make me think.
- Use thePrinciple of Least Astonishment.
Resources
QuotingDonald Knuth:
Programmers waste enormous amounts of time thinking about, or worrying about,the speed of non-critical parts of their programs, and these attempts atefficiency actually have a strong negative impact when debugging andmaintenance are considered. We should forget about small efficiencies, sayabout 97% of the time: premature optimization is the root of all evil. Yet weshould not pass up our opportunities in that critical 3%.
Understanding what is and isn’t "premature" is critical.
Why
- It is unknown upfront where the bottlenecks will be.
- After optimization, it might be harder to read and thus maintain.
How
- Make It Work Make It Right Make It Fast
- Don't optimize until you need to, and only after profiling you discover abottleneck to optimise.
Resources
The Boy Scouts of America have a simple rule that we can apply to ourprofession: "Leave the campground cleaner than you found it". The boy scout rulestates that we should always leave the code cleaner than we found it.
Why
- When making changes to an existing codebase the code quality tends to degrade,accumulating technical debt. Following the boy scout rule, we should mind thequality with each commit. Technical debt is resisted by continuousrefactoring, no matter how small.
How
- With each commit make sure it does not degrade the codebase quality.
- Any time someone sees some code that isn't as clear as it should be, theyshould take the opportunity to fix it right there and then.
Resources
Coupling between modules or components is their degree of mutualinterdependence; lower coupling is better. In other words, coupling is theprobability that code unit "B" will "break" after an unknown change to code unit"A".
Why
- A change in one module usually forces a ripple effect of changes in othermodules.
- Assembly of modules might require more effort and/or time due to the increasedinter-module dependency.
- A particular module might be harder to reuse and/or test because dependentmodules must be included.
- Developers might be afraid to change code because they aren't sure what mightbe affected.
How
- Eliminate, minimise, and reduce complexity of necessary relationships.
- By hiding implementation details, coupling is reduced.
- Apply theLaw of Demeter.
Resources
Don't talk to strangers.
Why
- It usually tightens coupling
- It might reveal too much implementation details
How
A method of an object may only call methods of:
- The object itself.
- An argument of the method.
- Any object created within the method.
- Any direct properties/fields of the object.
Resources
It is better to compose what an object can do than extend what it is. Composewhen there is a "has a" (or "uses a") relationship, inherit when "is a".
Why
- Less coupling between classes.
- Using inheritance, subclasses easily make assumptions, and breakLSP.
- Increase flexibility: accommodate future requirements changes, otherwiserequiring restructuring of business-domain classes in the inheritance model.
- Avoid problems often associated with relatively minor changes to aninheritance-based model including several generations of classes.
How
- Identify system object behaviors in separate interfaces, instead of creating ahierarchical relationship to distribute behaviors among business-domainclasses via inheritance.
- Test forLSP to decide when to inherit.
Resources
The basic idea of orthogonality is that things that are not relatedconceptually should not be related in the system.
Source:Be Orthogonal
It is associated with simplicity; the more orthogonal the design, the fewerexceptions. This makes it easier to learn, read and write programs in aprogramming language. The meaning of an orthogonal feature is independent ofcontext; the key parameters are symmetry and consistency.
Source:Orthogonality
Be conservative in what you do, be liberal in what you accept from others
Collaborating services depend on each others interfaces. Often the interfacesneed to evolve causing the other end to receive unspecified data. A naiveimplementation refuses to collaborate if the received data does not strictlyfollow the specification. A more sophisticated implementation will still workignoring the data it does not recognize.
Why
- Ensure that a provider can make changes to support new demands, while causingminimal breakage to their existing clients.
How
- Code that sends commands or data to other programs or machines should conformcompletely to the specifications, but code that receives input should acceptnon-conformant input as long as the meaning is clear.
Resources
IoC inverts the flow of control. It's also known as the Hollywood Principle,"Don't call us, we'll call you". A design principle in which custom-writtenportions of a computer program receive the flow of control from a genericframework. It carries the strong connotation that the reusable code and theproblem-specific code are developed independently even though they operatetogether in an application.
Why
- Increase modularity of the program and make it extensible.
- To decouple the execution of a task from implementation.
- To focus a module on the task it is designed for.
- To free modules from assumptions about other systems and instead rely oncontracts.
- To prevent side effects when replacing a module.
How
- Using Factory pattern
- Using Service Locator pattern
- Using Dependency Injection
- Using contextualized lookup
- Using Template Method pattern
- Using Strategy pattern
Resources
- Inversion of Control in Wikipedia
- Inversion of Control Containers and the Dependency Injection pattern
Cohesion of a single module or component is the degree to which itsresponsibilities form a meaningful unit. Higher cohesion is better.
Why
- Reduced module complexity
- Increased system maintainability, because logical changes in the domain affectfewer modules, and because changes in one module require fewer changes inother modules.
- Increased module reusability, because application developers will find thecomponent they need more easily among the cohesive set of operations providedby the module.
How
- Group related functionalities sharing a single responsibility (e.g. in amodule or class).
Resources
The LSP is all about expected behavior of objects:
Objects in a program should be replaceable with instances of their subtypeswithout altering the correctness of that program.
LSP is the L inSOLID.
Resources
Software entities (e.g. classes) should be open for extension, but closed formodification. Such an entity can allow its behavior to be modified, withoutaltering its source code.
Open/Closed is the O inSOLID.
Why
- Improve maintainability and stability by minimizing changes to existing code.
How
- Write classes that can be extended (as opposed to classes that can bemodified).
- Expose only the moving parts that need to change, hide everything else.
Resources
A class should never have more than one reason to change.
Long version: Every class should have a single responsibility, and thatresponsibility should be entirely encapsulated by the class. Responsibility canbe defined as a reason to change, so a class or module should have one, and onlyone, reason to change.
SRP is the S inSOLID.
Why
- Maintainability: changes should be necessary only in one module or class.
How
- ApplyCurly's Law.
Resources
A software module hides information (i.e. implementation details) by providingan interface, and not leak any unnecessary information.
Why
- When the implementation changes, the interface clients are using does not haveto change.
How
- Minimize accessibility of classes and members.
- Don’t expose member data in public.
- Avoid putting private implementation details into a class’s interface.
- Decrease coupling to hide more implementation details.
Resources
Curly's Law is about choosing a single, clearly defined goal for any particularbit of code: Do One Thing.
A good design identifies the hotspots that are most likely to change andencapsulates them behind an interface. When an anticipated change then occurs,the modifications are kept local.
Why
- To minimize required modifications when a change occurs.
How
- Encapsulate the concept that varies behind an interface.
- Possibly separate the varying concept into its own module.
Resources
Reduce fat interfaces into multiple smaller and more specific client specificinterfaces. An interface should be more dependent on the code that calls it thanthe code that implements it.
ISP is the I inSOLID.
Why
- Keep a system decoupled and thus easier to refactor, change, and redeploy.
How
- Avoid fat interfaces. Classes should never have to implement methods thatviolate theSingle responsibility principle.
Resources
The Command Query Separation principle states that each method should be eithera command that performs an action, or a query that returns data to the callerbut not both. Asking a question should not modify the answer.
With this principle applied the programmer can code with much more confidence.The query methods can be used anywhere and in any order since they do not mutatethe state. With commands one has to be more careful.
Why
- By clearly separating methods into queries and commands the programmer cancode with additional confidence without knowing each method's implementationdetails.
How
- Implement each method as either a query or a command
- Apply naming convention to method names that implies whether the method is aquery or a command
Resources
A subset of programming principles:
- Single Responsibility Principle
- Open/Closed Principle
- Liskov Substitution Principle
- Interface Segregation Principle
- Dependency Inversion Principle
The FIRST testing principles mean that tests should be Fast, Isolated,Repeatable, Self-validating and Timely.
Resources
The 3A's are a pattern to arrange and format code in unit tests.Arrange allnecessary preconditions and inputs.Act on the object or method under test.Assert that the expected results have occurred.
Resources
About
Categorized overview of programming principles & design patterns
Resources
Uh oh!
There was an error while loading.Please reload this page.