Monday, October 9, 2023

Dependency Inversion Principle

The Dependency Inversion Principle (DIP) states that high-level modules/classes should not depend on low-level modules/classes


Abstractions should not depend on details. Details should depend on abstractions.

The most important point you need to remember while developing real-time applications is always to keep the High-level and Low-level modules as loosely coupled as possible.

When one class is aware of  the design and implementation of another class, it increases the risk that , any changes made  to one class will disrupt  the other class. Therefore, it is important to maintain loose coupling between high-level and low-level modules/classes. To achieve this, both classes should depend on abstractions rather than having direct knowledge of each other. If this concept is currently unclear do not worry. By the end of this article, you will have a clear understanding of this concept through examples.

First, we will see an example without following the Dependency Inversion Principle. Then, we will identify the problems of not following the Dependency Inversion Principle. Finally, we will rewrite the same example using the Dependency Inversion Principle so that you can easily understand this concept

Create a Console Application and then add the following class files.









EmpDal.cs









DataAccessFactory.cs









EmpBal.cs








The following class has one constructor used to create an instance of the EmployeeDataAccessLogic class. Here, within the constructor, we call the static GetEmployeeDataAccessObj() method on the DataAccessFactory class, which will return an instance of EmployeeDataAccessLogic.


We then initialize the _EmployeeDataAccessLogic property with the returned instance. Additionally, we have one method, GetEmployeeDetails, which calls the GetEmployeeDetails method on the EmpDal instance to retrieve the employee details by employee ID.


So now, as per Dependency Inversion Principle

According to the definition of the Dependency Inversion Principle  High-Level module should not depend on Low-level modules. Both should depend on the abstraction.

From the above example, we need to identify High-Level Module (class) and the Low-Level Module (class) in our example. 

A High-Level Module is a module that always depends on other modules. So, in our example, the EmpBal class depends on the EmpDal class, so here, the EmpBal class is the high-level module, and the EmpDal class is the low-level module.

So, according to the first rule of the Dependency Inversion Principle in C#, the EmpBal class/module should not depend on the concrete EmpDal class/module. Instead, both classes should depend on an abstraction. However, in our example, the way we have implemented the code, the EmpBal depending on the EmpDal class, means that we are not following the first rule. In the later part of this article, I will modify the example to follow the Dependency Inversion Principle.

The second rule of the Dependency Inversion Principle states that Abstractions"  should not depend on details. Details should depend on "abstractions" 

Let us understand about abstraction Now

In the previous example the EmpBal and EmpDal are concrete classes, meaning we can create objects of them. That is means we are also not following the second rule of the Dependency Inversion Principle.

As per the Dependency Inversion Principle in C#, the EmpBal (High-Level Module) should not depend on the concrete EmpDal (Low-Level Module) class. Both classes should depend on Abstractions, meaning both classes should depend on an Interface or an Abstract Class.

Now, the question is what methods should be in interface or abstract class.

Now, let us create an interface to achieve this principle













Now, we need to implement the above interface in EmpDal as shown below.
















Now, 
we need to change the DataAccessFactory class. Here, we need to change the return type of the GetEmployeeDataAccessObj to IEmployeeDataAccessLogic as shown below








Now, we will change the EmpBal class code as shown below









That’s it. We have implemented the Dependency Inversion Principle in our example using C# language where the High-Level module (EmpBal) and Low-Level module (EmpDal) depend on abstraction (IEmployeeDataAccess). Also, abstraction (IEmployeeDataAccess) does not depend on details (EmpDal), but details depend on abstraction.








Now run the program.

Output












Solid Priciples

SOLID principles allows object oriented programming implementation in an efficient better way into project development

     S-->Single Responsibility Principle  [SRP]

     O-->Open Closed Principle           [OCP]

     L-->Liskov Substitution Principle   [LSP]

     I-->Interface Segregation Principle [ISP]

     D-->Dependency Inversion Principle  [DIP]

S-Single Responsibility Principle

This means that every class or similar structure in your code should have only one job.

The class should be provided with single responsibility related to a particular task.

A module or class should have a very small piece of responsibility  in the entire application, This also reduces number of bugs and  improves development speed and most importantly makes developer’s  life lot easier

Example










It looks fine, but it is not following SRP. 

The SendEmailTo and ValidateEmailAddres methods have nothing to do with the UserService class. Let's refract it.

Let's refract it to satisfy SRP












O: Open/Closed Principle

Software entities (classes, modules) should be opened for extension, but closed for modification.

This principle suggests that the class should be easily extended but there is no need to change its core implementations.

Now, the below code violates OCP principle if the bank introduces a new Account  type. the code to be modified for adding a new account type.



      







We can apply OCP by using interface (or) abstract class when you want to      extend functionality will create a new class to each type of acct type customer 

   











Note:

when we need corporate acct type, we can create a new class by extending        interface without modifying exiting class[no modification] but extension

  







In the above code three new classes are created; Regularsavingaccount,  SalarySavingAccount, and CorporateAccount, by extending them from IAccount.

This solves the problem of modification of class and by extending interface,  we can extend functionality.

Above code is implementing both OCP and SRP principle, as each class has  single is doing a single task and we are not modifying class and only doing  an extension.

In C#, Open/Closed principle can be applied using the following approaches:

Using Function Parameters

Using Extension methods

Using Classes, Abstract class, or Interface-based Inheritance

Generics

By using Interface











Now, some developers want to change the Method DebugDetails, So to satisfy there needs you need to modify the Logger class and either create a new method for them or modify the existing DebugDetails() method. If you change the existing DebugDetails() method then the other developers who don't want this change will also be affected.

To solve this problem is to use class based-inheritance (polymorphism) 









Now, a new class can inherit the Logger class and change one or more method behavior











Liskov Substitution Principle[LSP]


Base classes must be able to use objects of derived classes without knowing it. LSP states that the child class should be perfectly substitutable for their parent class.

Base class var should be able to reference derived class object, it is called Upcasting principle

When you derived a class from a base class then the derived class should correctly implement all the methods of the base class. It should not remove some methods by throwing NotImplementedException.

LSP says that the derived class should correctly implement the base class methods.











To correct above implementation, we need to refactor this code by introducing interface with method called GetShape.

 


namespace Demo
{
 class Program
 {
 static void Main(string[] args)
 {
 Shape shape = new Circle();
 Console.WriteLine(shape.GetShape());
 shape = new Triangle ();
 Console.WriteLine(shape.GetShape());
 }
 }
 
 public abstract class Shape
 {
 public abstract string GetShape();
 }
 
 public class Triangle: Shape
 {
 public override string GetShape()
 {
 return "Triangle";
 }
 }
 
 public class Circle: Triangle
 {
 public override string GetShape()
 {
 return "Circle";
 }
 }
}









Output

Circle

Triangle


I-->Interface Segration Principle[ISP]

class should not be forced to implement methods which it does not need, and the contracts should be broken down to thin ones

[break one interface into different interfaces].

Using ISP, we can create separate interfaces for each operation or            requirement rather than having a single interface with so many methods.

Example








We can resolve this violation by dividing IOrder Interface.












D-->Dependency Inversion Principle  [DIP]

The Dependency Inversion Principle (DIP) states that high-level modules/classes should not depend on low-level modules/classes


Abstractions should not depend on details. Details should depend on abstractions.

The most important point you need to remember while developing real-time applications is always to keep the High-level and Low-level modules as loosely coupled as possible.

Refer Next Article of Mine to know more about Dependency Injection.





Tuesday, October 3, 2023

Different Types of Loops in Typescript(For, While)

for Loop

The for loop is used to execute a block of code a given number of times, which is specified by a condition.

Example

for (let i = 0; i < 3; i++) {
    console.log ("Serial Number" + i);
  }

Output
Serial Number0 Serial Number1 Serial Number2

for...of Loop:

This will be used with arrays,lists,tuples

Example
for (let i = 0; i < 3; i++) {
    console.log ("Serial Number" + i);
  }
  let arr = [10, 20, 30, 40];

  for (var val of arr) {
    console.log(val);
  }

Output

Serial Number0 Serial Number1 Serial Number2 10 20 30 40


for...in Loop

This can be used with an array, list, or tuple. The for...in loop iterates through a list or collection and returns an index on each iteration.

for (let i = 0; i < 3; i++) {
    console.log ("Serial Number" + i);
  }
  let arr = [10, 20, 30, 40];

  for (var val of arr) {
    console.log(val);
  }
  for (var index in arr) {
    console.log(index);
 
    console.log(arr[index]);
  }

Output

10 20 30 40 0 10 1 20 2 30 3 40

While Loop
The loop runs until the condition value is met.

Example

let i: number = 2;

while (i < 4) {
    console.log( "Serial Number." + i )
    i++;
}

Output
Serial Number.2 Serial Number.3


do..while loop

The do..while loop is similar to the while loop, except that the condition is given at the end of the loop. The do..while loop runs the block of code at least once before checking for the specified condition. For the rest of the iterations, it runs the block of code only if the specified condition is met.

Example

Syntax:

do {
// code block to be executed
}
while (condition expression);

   
let i: number = 2;
do {
    console.log("Serial Number." + i )
    i++;
} while ( i < 4)


Output
Serial Number.2 Serial Number.3

Thursday, September 28, 2023

TypeScript Part 11(Tuple, Enum,Never)

Tuple

It is a new data type called Tuple. It can contains values of two different data types.

Example 
var empId: number = 1;
var empName: string = "Uday";        

// Using Tuple type variable we can combine above two variables into a single one as 
var employee: [number, string] = [1, "Uday"];
Tuple can include multiple data types as well. 

Example
var user: [number, string, boolean, number, string];// declare tuple variable
user = [1, "Uday", true, 20, "Admin"];// initialize tuple variable

Tuple Array
Example

var employee: [number, string][];
employee = [[1, "Uday"], [2, "Kumar"], [3, "Kittu"]];

How to access Tuple Elements
var employee: [number, string] = [1, "Uday"];
employee[0]; // returns 1
employee[1]; // returns "Uday"

Example

var user: [number, string, boolean, number, string];// declare tuple variable
user = [1, "Uday", true, 20, "Admin"]
console.log(user[0]);
console.log(user[1]);
console.log(user[2]);
console.log(user[3]);

Output










Add Elements to Tuple
var employee: [number, string] = [1, "Uday"];
employee.push(2, "Kumar"); 
console.log(employee); //Output: [1, 'Uday', 2, 'Kumar']

Example

var user: [number, string] = [1, "Uday"];
user.push(2, "Kumar");
console.log(employee);
console.log(user[0]);
console.log(user[1]);

Wednesday, September 27, 2023

Working with OnBlur and Focus Events

Blur: It specifies the actions to perform when element looses the focus.

Focus specifies the action to perform when element get focus.

Cut, Copy, Paste 

Specifies action to perform on cut, copy and paste functionality.

Example

Add a new component

ng g c eventsample6

ScreenShot



.ts changes

import { Component } from '@angular/core';

@Component({
  selector: 'app-eventsample6',
  templateUrl: './eventsample6.component.html',
  styleUrls: ['./eventsample6.component.css']
})
export class Eventsample6Component {
public txtName:any;
public msg:any;
public status:any;
public onBlur() {
  this.msg='';
  this.txtName=this.txtName.toUpperCase();
}
public onFocus()
{
  this.msg="Removed and Placed onto Clip Board";
}
public onCopy()
{
  this.status="Copied to ClipBoard";
}
public onPaste()
{
  this.status="Inserted from ClipBoard";
}
}

ScreenShot




















.html changes
<div class="container">
    <h2>User Details</h2>
    Name:
    <input (focus)="onFocus()" (blur)="onBlur()"
    (copy)="onCopy()"
    (paste)="onPaste()" type="text"
    [(ngModel)]="txtName">
    <span> {{msg}}</span>
    <br/>
    <div class="text-center">
        {{status}}
    </div>
</div>

















Next make changes on appmodule.ts and Index.html as shown in the previous examples

Output



Kubernetes

Prerequisites We assume anyone who wants to understand Kubernetes should have an understating of how the Docker works, how the Docker images...