Friday, January 8, 2021

Idea: An App runner desktop app

As organizations grows number of projects grows. Different project serves different purpose. some are BFF to API, some we use for configuring rules, some are normal documentations and others. All projects are being developed, maintained by the team and being used/tested by others. Sometime we need one project to test another project like you need APIs setup to test its web layer or another web project to test another we project or its integration.

In all that complexity, a single developer or mess has to open lots of Visual Studio instances, get latest of each project and then run it via plug button. And as you know keep opening lot of visual studios eats away all the memory, slows down your work and confuse a developer which instance he was working on.

After facing all of this I feel there should be an lightweight small UI to run all other project that we are not working on, we run it just to run other projects. A runner for api or web solution etc.

Lets call it app runner which runs processes just like XAMPP has which runs mysql, apache and other things from single UI, see its logs and all these kind of things.

How awesome would that be. No?

So lets create it :D



Tuesday, January 5, 2021

SOLID Principles

 Single Responsibility Principle

The class should have only one reason to change. Don't put functions in a single class that have different reasons to change like schema, business logic, UI design, calculations, validations, technology, storage mechanism, communication mechanism, underlying os, and many more. 

Don't Mix concerns in a single class.

But you have to define your own definition of concern or responsibility for your own system.

 Open Closed Principle

A class should be open for extension and closed for modification. like adding a new feature we have to recompile and redeploy old code with it too. Like If Statements, switch statements, enums, etc.

So, High-level code shouldn't know about the low-level details and neither the vice versa. They shouldn't know about each other's existence 

But please don't guess abstraction if you don't know to wait for the change to come and then make abstraction and refactor.

You can create abstractions for common known types like validations, database schema, UI, etc 

 Liskov Substitution Principle

The derived class could be used in place of the parent class without breaking the program. 

Covariance: You can't change the return type of the method 
Contravariance: you can change the parameter type of the method.

One subrule is you cannot return a new exception or put an extra check if you do that means It works with one type and throws exceptions for another type hence violating the LSP.

 Interface Segregation Principle

The client should not be forced to implement methods it's not using. That means there shouldn't be implemented exceptions or empty methods just to comply with the interface.

 Dependency Inversion Principle

High-level modules should not depend on low-level modules and vice versa but both should depend on abstraction; Abstractions should not depend on details.
That means
Business Logic shouldn't know how the database, logging, or emailing is working or neither should email know about business logic. Both should know each other about IEmailSernder or ILogger. 
And those interfaces shouldn't know how the concrete implementation is working.

whenever you see a new somewhere you got a tight coupling and we want loose coupling.

Big O Notation and Time and Space Complexity

Way of showing how the time it take to execute the program increases when the size of input increases.

Time Complexity

Types

O(1) =  Constant time complexity
O(n) = Linear time complexity
O(n2) = Quadratic time complexity

How to find

Just count the operations per execution for different sizes of n, assignment, conditional checks, calculations etc and count their multiple of n.


   public int Sum(int[] arr)
        {
            var total = 0; // 1 Assignment
            foreach (var elem in arr) // n Assignments
            {
                total = total + elem; // n (assignments) + n (additions)
            }

            return total; // 1 return
        }
  
Whole equations will be 1 + n + 2n + 1 = 3n + 2 = O(n) after dropping constants.

Space Complexity

How much memory (RAM) will the code consume/increases depends upon the input we provide that to code.
  • Primitive variable initialization takes up a memory, 
  • any array or string takes N memory depending on the size.
  • Classes memory is upto Sum of memory of all the variables inside it.
Variables in the loop/block are counted as O(1) because they are destroyed after the interaction in the modern languages. 
  public int Sum(int[] arr)
        {
            var total = 0; // 1 Assignment
            foreach (var elem in arr) // n Assignments
            {
                total = total + elem; // O(1)
            }

            return total;
        }
So it has Constant O(1) space complexity; Note: time complexity is prioritized over space complexity because processor are costlier, more resource intensive than the ram/memory and time is more expensive than the chips :P