SOLID
1
//////////////////////////////////// 1
S – Single Responsibility Principle (SRP)
Alta cohesión. Grado en que elementos diferentes de un sistema permanecen unidos para alcanzar un resultado
Bajo acoplamiento. Grado de interdependencia que tienen dos unidades de software entre sí
using System;
using [Link];
// Violation of SRP
class Employee
{
public string Name { get; set; }
public int EmployeeId { get; set; }
public void SaveToDatabase()
{
// Code to save employee data to a database
[Link]("Saved employee data to the database.");
}
public void GenerateReport()
{
// Code to generate an employee report
[Link]("Generated employee report.");
}
}
// Adhering to SRP
class EmployeeDataStorage
{
public void SaveToDatabase(Employee employee)
{
// Code to save employee data to a database
[Link]("Saved employee data to the database.");
}
}
class EmployeeReportGenerator
{
public void GenerateReport(Employee employee)
{
// Code to generate an employee report
[Link]("Generated employee report.");
}
}
class Program
{
static void Main()
{
Employee employee = new Employee
{
Name = "John Doe",
EmployeeId = 12345
};
EmployeeDataStorage dataStorage = new EmployeeDataStorage();
[Link](employee);
EmployeeReportGenerator reportGenerator = new EmployeeReportGenerator();
[Link](employee);
}
}
/////////////////////////////////
O – Open/Closed Principle (OCP)
Extend a class without modifying it
Open for extension, closed to Modification
Shape is open for extension because you can create new derived shapes by inheriting from it.
Rectangle and Circle are closed for modification because you can add new shapes without modifying the existing code.
using System;
public abstract class Shape
{
public abstract double Area();
}
public class Rectangle : Shape
{
public double Width { get; set; }
public double Height { get; set; }
public Rectangle(double width, double height)
{
Width = width;
Height = height;
}
public override double Area()
{
return Width * Height;
}
}
public class Circle : Shape
{
public double Radius { get; set; }
public Circle(double radius)
{
Radius = radius;
}
public override double Area()
{
return [Link] * Radius * Radius;
}
}
public class Program
{
public static void Main()
{
Shape rectangle = new Rectangle(5, 4);
Shape circle = new Circle(3);
CalculateAndDisplayArea(rectangle);
CalculateAndDisplayArea(circle);
}
public static void CalculateAndDisplayArea(Shape shape)
{
[Link]($"Area of the shape: {[Link]()}");
}
}
//////////////////////////////////////////
L – Liskov Substitution Principle (LSP)
Una clase base es aquella que no dependen ninguno de sus atributos u objetos de alguna otra clase
Las clases derivadas deben ser sustituibles por sus clases base
Assigning a Circle object to a Shape reference. This allows us to use a Circle object wherever we expect a Shape object
using System;
class Shape
{
public virtual void Draw()
{
[Link]("Drawing a shape");
}
}
class Circle : Shape
{
public override void Draw()
{
[Link]("Drawing a circle");
}
}
class Program
{
static void Main(string[] args)
{
// Using base class
Shape shape = new Shape();
[Link](); // Output: Drawing a shape
// Using derived class
Circle circle = new Circle();
[Link](); // Output: Drawing a circle
// Liskov Substitution Principle
// You can use a Circle object wherever you use a Shape object
Shape shape2 = new Circle();
[Link](); // Output: Drawing a circle
}
}
L: Liskov Substitution Principle
[Link]
///////////////////////////////////////
I – Interface Segregation Principle (ISP)
Interfaces specific to a type of client, that is, for a specific purpose
Consider a scenario where you have a large interface that contains several methods, and you want to use this interface in various classes.
If a class implements this interface, it is required to implement all the methods in the interface, even if it doesn't need them. This can
lead to:
Classes with unnecessary or empty method implementations, which violate the principle of keeping classes focused on their specific
responsibilities.
Maintenance challenges when the large interface is updated or changed, affecting all classes that implement it.
Create smaller, more focused interfaces with a specific set of methods related to a particular functionality.
Implement only the interfaces that are relevant to a class's behavior.
// Violating the ISP with a large interface
interface IWorker
{
void Work();
void Eat();
void Sleep();
}
class Worker : IWorker
{
public void Work()
{
[Link]("Worker is working.");
}
public void Eat()
{
[Link]("Worker is eating.");
}
public void Sleep()
{
[Link]("Worker is sleeping.");
}
}
// Following the ISP with smaller, focused interfaces
interface IWorker
{
void Work();
}
interface IEater
{
void Eat();
}
interface ISleeper
{
void Sleep();
}
class Worker : IWorker, IEater, ISleeper
{
public void Work()
{
[Link]("Worker is working.");
}
public void Eat()
{
[Link]("Worker is eating.");
}
public void Sleep()
{
[Link]("Worker is sleeping.");
}
}
////////////////////////////////////
D – Dependency Inversion Principle (DIP)
La abstracción consiste en aislar un elemento de su contexto
Depende de abstracciones, no de clases concretas
Los módulos de alto nivel no deberían depender de módulos de bajo nivel. Ambos deberían depender de abstracciones.
Las abstracciones no deberían depender de los detalles. Los detalles deberían depender de las abstracciones.
Reducir las dependencias entre los módulos del código, es decir, alcanzar un bajo acoplamiento de las clases.
If classes are dependent on each other the sw is tightly coupled
////////////////////////////////////////
POO
POLIMORFISMO
Habilidad de actuar en modos diferentes
Una variable puede apuntar a diferentes tipos de objetos
Los objetos pueden comportarse diferente dependiendo de su tipo
using System;
class Animal
{
public virtual void HacerSonido()
{
[Link]("El animal hace un sonido.");
}
}
class Perro : Animal
{
public override void HacerSonido()
{
[Link]("El perro ladra.");
}
}
class Gato : Animal
{
public override void HacerSonido()
{
[Link]("El gato maulla.");
}
}
class Program
{
static void Main()
{
Animal miAnimal;
miAnimal = new Perro();
[Link](); // Salida: El perro ladra
miAnimal = new Gato();
[Link](); // Salida: El gato maulla
}
}
////////////////////////////////////
ABSTRACCIÓN
Muestra sólo las características esenciales de una clase y esconde la información innecesaria
using System;
public abstract class FormaGeometrica
{
public abstract void Dibujar();
}
public class Circulo : FormaGeometrica
{
private int radio;
public Circulo(int radio)
{
[Link] = radio;
}
public override void Dibujar()
{
[Link]($"Dibujando un círculo con radio {radio}");
}
}
public class Rectangulo : FormaGeometrica
{
private int ancho;
private int alto;
public Rectangulo(int ancho, int alto)
{
[Link] = ancho;
[Link] = alto;
}
public override void Dibujar()
{
[Link]($"Dibujando un rectángulo de {ancho}x{alto}");
}
}
class Program
{
static void Main(string[] args)
{
FormaGeometrica forma1 = new Circulo(5);
FormaGeometrica forma2 = new Rectangulo(4, 6);
[Link]();
[Link]();
}
}
///////////////////////////////////////
ENCAPSULAR
Recolectar todos los elementos de una entidad al mismo nivel de abstracción
Person class encapsulates two private fields: name and age.
using System;
public class Person
{
// Private fields (attributes)
private string name;
private int age;
// Constructor to initialize the object
public Person(string name, int age)
{
[Link] = name;
[Link] = age;
}
// Public methods to access and modify the private fields
public string GetName()
{
return name;
}
public void SetName(string newName)
{
if ()
{
name = newName;
}
}
public int GetAge()
{
return age;
}
public void SetAge(int newAge)
{
if (newAge >= 0)
{
age = newAge;
}
}
// Public method to display information
public void DisplayInfo()
{
[Link]($"Name: {name}");
[Link]($"Age: {age}");
}
}
class Program
{
static void Main(string[] args)
{
// Create a Person object
Person person = new Person("John", 30);
// Access and modify object's data through methods
[Link]("Original Info:");
[Link]();
[Link]("Alice");
[Link](25);
[Link]("\nUpdated Info:");
[Link]();
}
}
//////////////////////////////////////
OVERLOAD
Overloading is having a method with the same name but different parameters
using System;
public class Calculator
{
public int Add(int num1, int num2)
{
return num1 + num2;
}
(method overloading)
public int Add(int num1, int num2, int num3)
{
return num1 + num2 + num3;
}
(method overloading)
public double Add(double num1, double num2)
{
return num1 + num2;
}
(method overloading)
public string Add(string str1, string str2)
{
return str1 + str2;
}
}
class Program
{
static void Main(string[] args)
{
Calculator calculator = new Calculator();
int sum1 = [Link](5, 7);
int sum2 = [Link](2, 4, 6);
double sum3 = [Link](3.5, 2.5);
string combinedString = [Link]("Hello, ", "world!");
[Link]("Sum 1: " + sum1);
[Link]("Sum 2: " + sum2);
[Link]("Sum 3: " + sum3);
[Link]("Combined String: " + combinedString);
}
}
////////////////////////////////////
STATIC CLASS
Cannot be instantiated
Can only contain static members
Used to group related utility methods
or provide a global point of access for functionality that doesn't depend on instance-specific data.
Here are some key characteristics and use cases for static classes:
1. Cannot Be Instantiated: You cannot create an instance (object) of a static class. It's meant to be used directly through
the class itself.
2. Static Members: All members (methods, properties, fields, events) within a static class must be declared as static. This
means they are associated with the class itself, rather than with instances of the class.
3. Global Access: Static classes provide a way to create globally accessible methods and data without having to create
instances of classes. You can call static methods and access static properties directly using the class name, e.g.,
`[Link]()`.
4. No State: Static classes don't have instance-specific state. They don't store data that varies between different
instances because they don't have instances.
5. Initialization: Static classes are initialized only once when they are first accessed, and their members remain in
memory for the lifetime of the application domain.
public static class MathUtils
{
public static int Add(int a, int b)
{
return a + b;
}
public static double SquareRoot(double x)
{
if (x < 0)
{
throw new ArgumentException("Input must be non-negative.");
}
return [Link](x);
}
}
class Program
{
static void Main(string[] args)
{
int sum = [Link](5, 3);
double sqrt = [Link](25.0);
[Link]("Sum: " + sum);
[Link]("Square Root: " + sqrt);
}
}
////////////////////////////////////
INTERNAL CLASS
It has restricted access within the assembly (or project)
Promotes encapsulation and modularity in your codebase.
1. Access Restriction: Internal classes are used to restrict access to certain classes, preventing them from being used by
code in other assemblies. This is useful for encapsulating implementation details and ensuring that certain classes are
only accessible within the assembly where they are defined.
2. Assembly Scope: The visibility of internal classes is limited to the assembly where they are defined. Other assemblies,
even those in the same project or solution, cannot access these classes.
3. Default Access Modifier: If you do not specify an access modifier for a class, it defaults to internal when defined at the
namespace level. For example:
namespace MyNamespace
{
class MyClass // This is an internal class by default
{
// Class members here
}
}
```
4. Explicit Declaration: You can also explicitly declare a class as internal using the `internal` keyword:
```csharp
internal class MyInternalClass
{
// Class members here
}
```
5. Usages: Internal classes are commonly used for implementing helper classes, service classes, or other types that
should not be exposed to external code. They are also used to define classes that should not be part of the public API of
a library or component.
6. Friend Assemblies: In some cases, you may want to allow specific external assemblies to access your internal classes.
This can be achieved by using the `InternalsVisibleTo` attribute in the AssemblyInfo file of your assembly. This attribute
specifies which other assemblies are considered "friend" assemblies and can access internal types and members.
using System;
namespace AssemblyA
{
internal class InternalClassA
{
public void DoSomethingInternal()
{
[Link]("InternalClassA is doing something.");
}
}
}
////////////////////////////////////
ABSTRACT CLASS
////////////////////////////////////
When different properties and functions of a real-world entity are grouped or embedded into a single element, it is
called an "object"
>Las interfaces sólo pueden contener métodos
abstractos y constantes
Final significa que
no puede ser heredado por otras clases
>Through inheritance you can create
relationships between child objects by extending them to their parent objects by inheriting their behavior
>Difference between abstract class and interface, an interface has abstract methods without
Implementing
An abstract class must have at least an
abstract method
>In passing by value, a
modification only affects the copy [kapi]
>>static class
The one used without creating an object
>Types of exceptions: EER
Error-> Not recoverable
Exception->Not final, caught outside of runtime
Runtime-> During program execution
>A constructor is a method used to
initialize the state of an object
Inteligencia artificial es la ciencia que intenta la creación de programas para máquinas que
imiten el comportamiento y la comprensión humana
Un programa es un conjunto de instrucciones escritas en un
lenguaje de programación
>Cohesión es el grado de interdependencia entre los
elementos
>Virtual function
Is a member function of a
class
Its functionality can be overridden in its
derived class
>>An Internal class is limited to the
project in which it is defined
>>An abstract class
Does not allow to create
instances of it
It only serves to be
inherited as base class
It has the methods defined but without any
functionality
In it we can indicate the access modifier, while in interfaces
we can't modify it
We can only use an abstract class as a
base
We can include a constructor, while
on an interface we can´t
Example of an abstract class
public abstract class Pieza
{
public abstract decimal Area();
protected abstract decimal Perimetro();
}
public class Cuadrado : Pieza
{
readonly decimal Lado;
public Cuadrado(decimal lado)
{
Lado = lado;
}
public override decimal Area()
{
return Lado * Lado;
}
public override decimal Perimetro()
{
return Lado * 4;
}
}
Una clase sealed es la última de una jerarquía, por lo que no podrá ser utilizada como
base de otra clase
Función friend
Es un amigo de una clase a la que se le permite acceder a datos públicos, privados o
protegidos en esa misma clase
Si ella se define fuera de la clase
no se puede acceder a la información
El método Finalize
Ayuda a realizar operaciones de
limpieza en los recursos que no se utilizan
Está
protegido
Cuando utilizamos interfaces, podemos implementar múltiples
Interfaces
Desde C# 8 podemos crear elementos
por defecto
Tipos de constructores: default, parameterized, copy,
Static and private
///////////////////////////////////////////////
Que concepto permite a los detalles que contiene una clase, no estén visibles para otras clases y objetos que la usan?
Encapsulación
El polimorfismo ocurre cuando los métodos de la clase hija:
Mantienen el mismo valor de retorno y los argumentos que la clase padre, pero se implementan de forma diferente
Polimorphism the Ability for a message or data to be processed: A. in mfore than one form