flyweight and proxy design patterns

This commit is contained in:
Claudiu Farcas
2021-04-24 02:31:17 +03:00
parent 1700df79fe
commit c19cf3d354
3 changed files with 147 additions and 1 deletions
+64
View File
@@ -0,0 +1,64 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace design_patterns.structural.flyweight
{
/// <summary>
/// Flyweight is a structural design pattern that lets you
/// fit more objects into the available amount of RAM
/// by sharing common parts of state between multiple objects
/// instead of keeping all of the data in each object.
///
/// - to avoid redundancy of stored data
/// </summary>
public class FlyweightSample
{
private static readonly string[] availableNames = {"alfa", "beta", "gama"};
public static async Task Run()
{
Console.WriteLine("Structural - Flyweight");
Random rnd = new Random();
List<Person> lst = new List<Person>();
for (int i = 0; i < 100000; i++)
{
lst.Add(new Person(availableNames[rnd.Next(0,2)]));
}
System.Console.WriteLine($"lst has {lst.Count} persons.");
}
public class Person {
// data storage
private static List<string> names = new List<string>();
private int nameIndex = -1;
public Person(string name) {
Name = name;
}
public string Name {
get {
return names[nameIndex];
}
set {
// optimize names storage by place it into
// a centralized storage and reference data
// by an index
nameIndex = GetIndex(value);
}
}
private static int GetIndex(string name) {
var idx = names.IndexOf(name);
if(idx==-1) {
names.Add(name);
idx = names.Count-1;
}
return idx;
}
}
}
}
+78
View File
@@ -0,0 +1,78 @@
using System.Collections.Concurrent;
using System;
using System.Threading.Tasks;
namespace design_patterns.structural.proxy
{
/// <summary>
/// Proxy is a structural design pattern that lets you
/// provide a substitute or placeholder for another object.
/// A proxy controls access to the original object,
/// allowing you to perform something either before or after
/// the request gets through to the original object.
///
/// - Create a new proxy class with the same interface
/// as an original service object.
/// - Then you update your app so that it passes the proxy object
/// to all of the original objects clients.
/// - Upon receiving a request from a client, the proxy creates
/// a real service object and delegates all the work to it.
///
/// Usages:
/// - Lazy initialization (virtual proxy).
/// - Access control (protection proxy).
/// - Local execution of a remote service (remote proxy).
/// - Logging requests (logging proxy).
/// - Caching request results (caching proxy).
/// - Smart reference. To dismiss a object/rsource once there are no clients using it.
/// </summary>
public class ProxySample
{
public static async Task Run()
{
Console.WriteLine("Structural - Proxy");
var proxy = new ProxyService();
var data = Guid.NewGuid().ToString();
proxy.ProcessData(data);
proxy.ProcessData(data);
}
public interface IService {
public bool ProcessData(string input);
}
public class RealService : IService
{
public bool ProcessData(string input)
{
System.Console.WriteLine($"Real service with input: {input}");
return input.Length % 2 == 0;
}
}
public class ProxyService : IService
{
// can do lazy loading
private Lazy<RealService> realService =
new Lazy<RealService>(() => new RealService());
private static ConcurrentDictionary<string, bool> cache = new ConcurrentDictionary<string, bool>();
public bool ProcessData(string input)
{
// can log info
System.Console.WriteLine($"Proxy service started with input {input}");
var service = realService.Value;
// could cache the result for later user
if(!cache.TryGetValue(input, out bool result)){
result = service.ProcessData(input);
cache[input] = result;
}
// can log info
System.Console.WriteLine($"Proxy service ended with result {result}");
return result;
}
}
}
}