diff --git a/Program.cs b/Program.cs
index ac77235..35d44e7 100644
--- a/Program.cs
+++ b/Program.cs
@@ -12,6 +12,8 @@ using design_patterns.structural.bridge;
using design_patterns.structural.composite;
using design_patterns.structural.decorator;
using design_patterns.structural.facade;
+using design_patterns.structural.flyweight;
+using design_patterns.structural.proxy;
namespace design_patterns
{
@@ -35,7 +37,9 @@ namespace design_patterns
// await BridgeSample.Run();
// await CompositeSample.Run();
// await DecoratorSample.Run();
- await FacadeSample.Run();
+ // await FacadeSample.Run();
+ // await FlyweightSample.Run();
+ await ProxySample.Run();
}
catch (System.Exception ex)
{
diff --git a/structural/flyweight/FlyweightSample.cs b/structural/flyweight/FlyweightSample.cs
new file mode 100644
index 0000000..8c25fa4
--- /dev/null
+++ b/structural/flyweight/FlyweightSample.cs
@@ -0,0 +1,64 @@
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace design_patterns.structural.flyweight
+{
+ ///
+ /// 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
+ ///
+ 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 lst = new List();
+ 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 names = new List();
+
+ 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;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/structural/proxy/ProxySample.cs b/structural/proxy/ProxySample.cs
new file mode 100644
index 0000000..7bba390
--- /dev/null
+++ b/structural/proxy/ProxySample.cs
@@ -0,0 +1,78 @@
+using System.Collections.Concurrent;
+using System;
+using System.Threading.Tasks;
+
+namespace design_patterns.structural.proxy
+{
+ ///
+ /// 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 object’s 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.
+ ///
+ 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 =
+ new Lazy(() => new RealService());
+
+ private static ConcurrentDictionary cache = new ConcurrentDictionary();
+ 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;
+ }
+ }
+ }
+}
\ No newline at end of file