SOLID principles
| Create Date: October 13, 2020 at 12:38 AM         | Tag: DESIGN PATTERN         | Author Name: Sun, Charles |
Single responsibility principle:
Each software module should have one and only one reason to change.
The individual classes and methods in applications define what the application does, and how it does it.
Open/Closed principle:
Software entities (classes, modules, funcitons, etc.) should be open for extension, but closed for modification.
Liskov (LSP) violations:
Detecing Liskov viliations in the code:
- Type chekcing with is or as in polymorphic code
- Null checks
- NotImplementedException
Interface segregation principle:
Clients should not be forced to denpend on methods they do not use.
interface implements interface.
Dependency inversion principle:
High-level modules should not depend on low-level modules. Both shoudl depend on abstractions.
Abstractions should not depend on details.
Details should depend on abstractions.
New CommentSingleton
| Create Date: August 23, 2020 at 08:40 PM         | Tag: DESIGN PATTERN         | Author Name: Sun, Charles |
What is a singleton?
Singleton is a class which only allows a single instance.
complicated thread safe version, but it helps to understand the principle:
//cannot add static because instructor is not static.
public class Singleton
{
private static readonly object mutex = new object();
//The volatile keyword indicates that a field might be modified by multiple threads that are executing at the same time. Fields that are declared volatile are not subject to compiler optimizations that assume access by a single thread. This ensures that the most up-to-date value is present in the field at all times.
private static volatile Singleton instance;
private Singleton()
{
//Stuff that must only happen once.
}
public static Singleton Instance
{
get
{
if (instance == null)
{
//make sure thread safe
lock (mutex)
{
if (instance == null)
{
instance = new Singleton();
}
}
}
return instance;
}
}
//This the raison d'etre for the class
public void DoSomething()
{
//This must be thread-safe!
}
}
Simple version: let the core framework manage the locking, mutex, and volatile stuff for you.
public class Singleton
{
private Singleton()
{
//Stuff that must only happen once.
}
public static Singleton Instance { get; } = new Singleton();
//This the raison d'etre for the class
public void DoSomething()
{
//This must be thread-safe!
}
}
public class Singleton
{
private static readonly Singleton instance = new Singleton();
private Singleton()
{
//Stuff that must only happen once.
}
public static Singleton Instance { get { return instance; } }
//This the raison d'etre for the class
public void DoSomething()
{
//This must be thread-safe!
}
}
public class Singleton
{
//only works for .net 4 or above.Fully lazy :)
private static readonly Lazy lazyInstance =
new Lazy(() => new Singleton(), true);
private Singleton()
{
//Stuff that must only happen once.
}
public static Singleton Instance { get { return lazyInstance.Value; } }
//This the raison d'etre for the class
public void DoSomething()
{
//This must be thread-safe!
}
}
New Comment
Design Patterns: Decorator
| Create Date: July 16, 2020 at 03:13 AM         | Tag: DESIGN PATTERN         | Author Name: Sun, Charles |
Decorator pattern use cases:
- cross cutting concerns: logging, performance tracking, caching, authorization etc.
- manipulate data going to / form component. e.g.
- there are certain fields of an object we need to encrypt an ddecrypt before being pass to a component.
- there are fields whose values we need to convert. e.g. from US standard units to the metric system.
what if your component does not have an interface / extend from a base class?
Extract an interface from the class. Edit → refactor → Extract Interface in VS. (Ctrl + R, then Ctrl + I)
What if you cannot change the component?
use adapter pattern and then the adapter pattern implements the interface you have extracted.
New Comment