- Structural pattern
- The intent of this pattern is to use sharing to support large number of fine-grained objects efficiently. It does that by sharing parts of the state between these objects instead of keeping all the state in all of the objects.
- Move the common properties to different class(here Product class). Product class will have Name, Description, Type, Price. Product class is brand new class to achieve the flyweight pattern.
- Create a new factory – PSFlyWeightFactory. It Caches the Product type. Brand new class.
- PSItemFactory – takes the common cached Product + the one varying property serialNumber to create the OrderItem. Existing class, some modification required.
- Order class – no modification
- OrderItem – common properties are commented and moved to Product class.
- Program.cs- few modification required
- PSFlyWeightFactory pSFlyWeightFactory = new PSFlyWeightFactory();
- PSItemFactory pSItemFactory = new PSItemFactory(pSFlyWeightFactory);
PSItemFactory
using FlyweightPattern;
namespace WithoutFlyweightPattern
{
public class PSItemFactory
{
private readonly PSFlyWeightFactory _pSFlyWeightFactory;
public PSItemFactory(PSFlyWeightFactory pSFlyWeightFactory)
{
_pSFlyWeightFactory = pSFlyWeightFactory;
}
public OrderItem Create(PSSeries series, string serialNumber)
{
Product product = _pSFlyWeightFactory.Create(series);
return new OrderItem(product, serialNumber);
//switch (series)
//{
// case PSSeries.PS5ConsoleEdition:
// return new OrderItem("PS5 Console Edition",
// "PS5 Console Edition with a Console free", ProductType.GamingConsole, 54990, serialNumber);
// case PSSeries.PS5DiscEdition:
// return new OrderItem("PS5 Disc Edition",
// "PS5 Disc Edition with a webcam", ProductType.GamingConsole, 54990, serialNumber);
// case PSSeries.PS4:
// return new OrderItem("PS4 Console",
// "PS4 Console old but still the best", ProductType.GamingConsole, 25000, serialNumber);
// case PSSeries.PS3:
// return new OrderItem("PS3 Console Edition",
// "PS3 2006 product", ProductType.GamingConsole, 15000, serialNumber);
// default:
// throw new Exception("Unknown Gaming Console");
//}
}
}
public enum PSSeries
{
PS5DiscEdition,
PS5ConsoleEdition,
PS4,
PS3
}
}
PSFlyWeightFactory
using WithoutFlyweightPattern;
namespace FlyweightPattern
{
public class PSFlyWeightFactory
{
private readonly Dictionary _psSeries;
public PSFlyWeightFactory()
{
_psSeries = new Dictionary();
}
public Product Create(PSSeries series)
{
if (!_psSeries.ContainsKey(series))
{
switch (series)
{
case PSSeries.PS5ConsoleEdition:
_psSeries.Add(series, new Product("PS5 Console Edition",
"PS5 Console Edition with a Console free", ProductType.GamingConsole, 54990));
break;
case PSSeries.PS5DiscEdition:
_psSeries.Add(series,new Product("PS5 Disc Edition",
"PS5 Disc Edition with a webcam", ProductType.GamingConsole, 54990));
break;
case PSSeries.PS4:
_psSeries.Add(series, new Product("PS4 Console",
"PS4 Console old but still the best", ProductType.GamingConsole, 25000));
break;
case PSSeries.PS3:
_psSeries.Add(series, new Product("PS3 Console",
"PS3 2006 product", ProductType.GamingConsole, 15000));
break;
default:
break;
}
}
return _psSeries[series];
}
}
}
Product.cs
using WithoutFlyweightPattern;
namespace FlyweightPattern
{
public class Product
{
public Product(string name, string description, ProductType type, double price)
{
Name = name;
Description = description;
Type = type;
Price = price;
}
public string Name { get; set; }
public string Description { get; set; }
public ProductType Type { get; set; }
public double Price { get; set; }
}
}
Order and OrderItem
using FlyweightPattern;
namespace WithoutFlyweightPattern
{
public class OrderItem
{
//step1: comment
//public string Name { get; set; }
//public string Description { get; set; }
//public ProductType Type { get; set; }
//public double Price { get; set; }
//step2..
//public Product Product { get; set; }
//public string SerialNumber { get; set; }
//step3..no setter
//make it completely immutable ...
public Product Product { get;}
public string SerialNumber { get;}
public OrderItem(Product product, string serialNumber)
{
//Name = name;
//Description = description;
//Type = type;
//Price = price;
Product = product;
SerialNumber = serialNumber;
}
}
public enum ProductType
{
GamingConsole,
Desktops,
Laptop
}
}
namespace WithoutFlyweightPattern
{
public class Order
{
private readonly List _items;
public Order()
{
_items = new List();
}
public void Add(OrderItem item)
{
_items.Add(item);
}
}
}
PROGRAM.CS
using FlyweightPattern;
using System.Text;
using WithoutFlyweightPattern;
class Program
{
private static int orderCount = 100000;
static void Main()
{
//commen this
//PSItemFactory pSItemFactory = new PSItemFactory();
//make this change..
PSFlyWeightFactory pSFlyWeightFactory = new PSFlyWeightFactory();
PSItemFactory pSItemFactory = new PSItemFactory(pSFlyWeightFactory);
List orders = new List();
//from front dropdown you fetch the PS type
//for example : it is PS5ConsoleEdition
//1 lakh order count.....
var orderPsType = PSSeries.PS5ConsoleEdition;
for (int i = 0; i < orderCount; i++)
{
Order order = new Order();
OrderItem psItem = pSItemFactory.Create(orderPsType, ToBase36((ulong)i));
order.Add(psItem);
orders.Add(order);
}
Console.ReadKey();
}
private static string ToBase36(ulong value)
{
const string base36 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var sb = new StringBuilder(9);
do
{
sb.Insert(0, base36[(byte)(value % 36)]);
value /= 36;
} while (value != 0);
var paddedString = "ABC" + sb.ToString().PadLeft(6, '0');
return paddedString;
}
}
OUTPUT - BEFORE
OUTPUT - AFTER
GITHUB