So you want to be a developer
This repository is where I store findings, learnings, hopefully best practices and ways of working.
Clone if you find the structure usable.
bool
, int
, float
, double
, decimal
, char
Data structures built from primitive and other complex types.
(C# struct
has only primitive types)
A problem solution described in steps.
Big-O notation, function which describes increase in run time
from size of input data
.
- Ω - lower bounded by, Θ - lower and upper bounded by, O - upper bounded by
- Worst case, Best case, Average case.
Ex. QuickSort: Best & Average case:
O(n * log(n))
, Worst case:O(n^2)
Ex. Binary chop: Best case:O(1)
, Average and Worst case:O(log(n))
Proof for finding Big-O for algorithms.
Allows access to the method from the class definition (instead of the instanciated object)
public static int Max(int a, int b);
-> Math.Max(5, 3)
public static int WordCount(this String str);
-> "Hello World".WordCount()
Change to data that is not returned by the function.
in
instanciated outside, not allowed to be change inside. Pass by reference.
ref
needs to be instanciated before being passed. Data flows in and out.
out
must be instanciated inside. Data flows only out.
public static bool TryParse (string input, out Guid result);
ref readonly
instanciated outside, not allowed to be change inside.
Don't Repead Yourself. When you feel that you are almost writing the same lines of code, try to refactor and extract that logic into its own function/method/component/class/program.
A Class should have one responsibility and not become "god objects" that does everything.
A Class should be Open for extension but Closed for modification. Try not to modify the current class, make it inherit another interface if possilble.
Subclasses should implement the full baseclass. Do not force the classes using the interface/abstract class to do sanity checks from exceptions thrown or nulls returned in its implemented methods. "If it quacks like a duck, looks like a duck but needs batteries - you probably have the wrong abstraction"
Small and specific interfaces, also called role interfaces. A class that implements an interface should not be forced to implement methods it is not interested in.
A Class should not create its dependencies, it should get them as input.
Separate your program into non-overlapping features.
Clean Code (Summary of 'Clean code' by Robert C. Martin)
- Follow standard conventions.
- Keep it simple stupid. Simpler is always better. Reduce complexity as much as possible.
- Boy scout rule. Leave the campground cleaner than you found it.
- Always find root cause. Always look for the root cause of a problem.
- Keep configurable data at high levels.
- Prefer polymorphism to if/else or switch/case.
- Separate multi-threading code.
- Prevent over-configurability.
- Use dependency injection.
- Follow Law of Demeter. A class should know only its direct dependencies.
- Be consistent. If you do something a certain way, do all similar things in the same way.
- Use explanatory variables.
- Encapsulate boundary conditions. Boundary conditions are hard to keep track of. Put the processing for them in one place.
- Prefer dedicated value objects to primitive type.
- Avoid logical dependency. Don't write methods which works correctly depending on something else in the same class.
- Avoid negative conditionals.
- Choose descriptive and unambiguous names.
- Make meaningful distinction.
- Use pronounceable names.
- Use searchable names.
- Replace magic numbers with named constants.
- Avoid encodings. Don't append prefixes or type information. Functions rules
- Small.
- Do one thing.
- Use descriptive names.
- Prefer fewer arguments.
- Have no side effects.
- Don't use flag arguments. Split method into several independent methods that can be called from the client without the flag.
- Always try to explain yourself in code.
- Don't be redundant.
- Don't add obvious noise.
- Don't use closing brace comments.
- Don't comment out code. Just remove.
- Use as explanation of intent.
- Use as clarification of code.
- Use as warning of consequences.
- Separate concepts vertically.
- Related code should appear vertically dense.
- Declare variables close to their usage.
- Dependent functions should be close.
- Similar functions should be close.
- Place functions in the downward direction.
- Keep lines short.
- Don't use horizontal alignment.
- Use white space to associate related things and disassociate weakly related.
- Don't break indentation.
- Hide internal structure.
- Prefer data structures.
- Avoid hybrids structures (half object and half data).
- Should be small.
- Do one thing.
- Small number of instance variables.
- Base class should know nothing about their derivatives.
- Better to have many functions than to pass some code into a function to select a behavior.
- Prefer non-static methods to static methods.
- One assert per test.
- Readable.
- Fast.
- Independent.
- Repeatable.
- Rigidity. The software is difficult to change. A small change causes a cascade of subsequent changes.
- Fragility. The software breaks in many places due to a single change.
- Immobility. You cannot reuse parts of the code in other projects because of involved risks and high effort.
- Needless Complexity.
- Needless Repetition.
- Opacity. The code is hard to understand.
Setup the data for the test
Do the operation to test
Compare to the expected result
Write tests prior to code, make the test work
Given, When, Then by Martin Fowler
Separate your ORM from your business logic. Allowing the communication with the Database and conversion into data entities to be separated from the business/service logic. https://www.youtube.com/watch?v=rtXpYpZdOzM
Encapsulates data model change transactions. Owns the "SaveChanges" action. One UoW is used in tandem with several repositories.
"...a chain of receiver objects having the responsibility, depending on run-time conditions, to either handle a request or forward it to the next receiver on the chain." - Wiki
Ex. Repositoriy with CoR:
The Service layer shouldn't know if there's a Cache or that some data might be located in an archived table. The Service should only request the data from the repository. With a CoR implementation on a IXRepository
as XRepoCache() -> XRepoSQL() -> XRepoArchive()
the Service only needs to ask the start of the chain for data instead of doing logic for if the data is in the cache or not.
The chain itself is build by each node implementing the repository interface with the addition of a IXRepository next
property to another repository of the same interface. Logic is moved into the repository on what should be done if it's a hit or miss.
Separates the business logic from the presentation layers.
https://www.youtube.com/watch?v=_lwCVE_XgqI
MVC standard is the /Controller, /Model, /Views folder setup. A new way of looking at this is per Feature approach: /Features/<feature>/Controller, /Features/<feature>/Models, /Features/<feature>/Views. Feature Folders vs Tech Foldes
Need a new ViewResolver so MVC can find the Feature views in their new folder structure.
See OdeToCode/AddFeatureFolders for a good starting point on adding viewPaths.
- Functional Components
const FuncComp = () => {}
- Class Components
class ClassComp extends React.Component {
render() {}
}
Component implements the shouldComponentUpdate lifecycle function with return true
The Key attribute allows react to find the correct node in the virtual DOM to update.
- Don't use the
i
in.map()
if you add or remove elements! Performance & React: Measuring and Fixing Common Bottlenecks Lin Clark: A cartoon guide to performance in React - JSConf Iceland 2016
Smart Components, connected to the Redux state via the HOC connect(mapState, mapDispatch)().
Allows the component to map state data into its props and exposes the dispatch function for triggering actions.
The larger the app, the lower level to Connect. A low level Connect can save workloads higher up from fewer rerenders.
MapStateToProps is they way to make the component "smart", listening to some part or parts of the state. To avoid unnecessary re-renders make sure that you don't make calculations here (or handle it with a specific shouldComponentUpdate()). ex. Component C listens to part A and B from the state, in mStP() we calculate AB from A and B. props.AB will never be shallowly equal to prevProps.AB.
Dispatched from the app to modify the global state, (or trigger other middlware actions).
A chain of listening services that might manipulate, trigger new or delete actions. Any calls to the outside of the react app should be handled with a middleware. I.e. an ApiMiddleware for external API calls.
A chain of listening services that define and manipulate the global state, called the store.
Methods for retreiving data from the store.