This document discusses strategies for implementing object-oriented design principles in .NET C# projects. It begins with an overview of the Bridge design pattern and object-oriented programming concepts like polymorphism. It then explains each of the five SOLID principles: single responsibility, open/closed, Liskov substitution, interface segregation, and dependency inversion. Code examples are provided to illustrate how to apply each principle properly and avoid common pitfalls.
4. Despre ce vom vorbi azi?
Bridge Design Pattern
Object Oriented Programming
SOLID Principles
Single Responsibility Principle
Open Closed Principle
Liskov Substitution Principle
Interface Segregation Principle
Dependency Inversion Principle
Q and A
5. Bridge Design Pattern
Structural Design Pattern.
Decouples an abstraction from its
implementation so that the two can
vary independently.
6.
7. public class RedColor { }
public class BlueColor { }
public class Shape { }
public class RedCircle : Shape
{
public RedColor Color { get; set; }
}
public class BlueCircle : Shape
{
public BlueColor Color { get; set; }
}
public class RedSquare : Shape
{
public RedColor Color { get; set; }
}
public class BlueSquare : Shape
{
public BlueColor Color { get; set; }
}
8.
9. public interface IColor { }
public class RedColor : IColor { }
public class BlueColor : IColor { }
public class Shape
{
public IColor Color { get; set; }
}
public class Circle : Shape { }
public class Square : Shape { }
10. Shape redCircle = new Circle
{
Color = new RedColor();
}
Shape blueCircle = new Circle
{
Color = new BlueCircle();
}
20. Single Responsibility Principle
"Every software class should have only
one reason to change.“
This means that every class should have
Everything in that class should be
purpose.
21. public class UserCreateCommand
{
public void Create(User user)
{
InsertIntoDatabase(user);
SendNotificationEmail(user);
}
private void InsertIntoDatabase(User user) { }
private void SendNotificationEmail(User user) { }
}
22. public class UserCreateCommand
{
public void Create(User user)
{
InsertIntoDatabase(user);
SendNotificationEmail(user);
}
private void InsertIntoDatabase(User user) { }
private void SendNotificationEmail(User user) { }
}
23. public class EmailSender
{
public void SendNotificationEmail(User user) { }
}
public class UserCreateCommand
{
private readonly EmailSender _emailSender;
public UserCreateCommand()
{
_emailSender = new EmailSender();
}
public void Create(User user)
{
InsertIntoDatabase(user);
_emailSender.SendNotificationEmail(user);
}
}
24. Open Closed Principle
"A software module/class is open for extension and
closed for modification.“
"Open for extension" means we must design our
new functionality can be added only when new
"Closed for modification" means once we developed a
gone through unit testing, then we should not alter it
specific change request.
25. OCP - Contracts
public class GetPersonResponseDto
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
}
26. OCP - Contracts
public class GetPersonResponseDto
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Age { get; set; }
public string Address { get; set; }
}
28. OCP - Classes
public class Repository<T>
{
public int Save(T entity) { }
public void Delete(T entity) { }
}
29. OCP – Classes - Polimorphism
public class Repository<T>
{
public virtual void Save(T entity) { }
}
public class ExtendedRepository<T> : Repository<T>
{
public override void Save(T entity)
{
// do stuff
base.Save(entity);
}
}
30. Liskov Substitution Principle
“You should be able to use any derived class instead of a
parent class and have it behave in the same manner without
manner without modification“.
It ensures that a derived class does not affect the behavior of the
parent class.
This principle is just an extension of the Open Closed Principle,
and we must ensure that newly derived classes extend the base
classes without changing their behavior.
31. Liskov Substitution Principle
public class RedColor
{
public void Splash() { }
public virtual string GetColor()
{
return "Red";
}
}
public class BlueColor : RedColor
{
public override string GetColor()
{
return "Blue";
}
}
33. Liskov Substitution Principle
public abstract class ColorBase
{
public void Splash() { }
public abstract string GetColor();
}
public class RedColor : ColorBase
{
public override string GetColor()
{
return "Red";
}
}
public class BlueColor : ColorBase
{
public override string GetColor()
{
return "Blue";
}
}
34. Interface Segregation Principle
“Clients should not be forced to
implement interfaces they don't use”.
Instead of a header interface, many small
preferred based on groups of methods,
one submodule.
38. Interface Segregation Principle
public class Shape : IShape { }
Shape shape = new Shape();
IColor color = shape as IColor;
IGetColor getColor = shape as IGetColor;
ISetColor setColor = shape as ISetColor;
IGetNumberOfSides getNumberOfSides = shape as IGetNumberOfSides;
40. public class EmailSender
{
public void SendNotificationEmail(User user) { }
}
public class UserCreateCommand
{
private readonly EmailSender _emailSender;
public UserCreateCommand()
{
_emailSender = new EmailSender();
}
public void Create(User user)
{
InsertIntoDatabase(user);
_emailSender.SendNotificationEmail(user);
}
}
41. public interface IEmailSender
{
void SendNotificationEmail(User user) { }
}
public class UserCreateCommand
{
private readonly IEmailSender _emailSender;
public UserCreateCommand(IEmailSender emailSender)
{
_emailSender = emailSender;
}
public void Create(User user)
{
InsertIntoDatabase(user);
_emailSender.SendNotificationEmail(user);
}
}