\$\begingroup\$
\$\endgroup\$
As a practice and self-development exercise I have decided to implement design patterns in C#.
I am using polish cuisine as an example in my implementations. In this project I implemented Prototype design pattern.
Model:
public static class PierogiTypes
{
public const string WithPotatoesAndCheese = "with potatoes and cheese";
public const string WithGroat = "with groat";
public const string WithCabbage = "with cabbage";
public const string WithMeat = "with meat";
public const string WithStrawberries = "with strawberries";
public const string WithBlueberries = "with blueberries";
public const string WithPotatoesAndCheeseButAlsoWithYoghurtAndKetchup = "with potatoes and cheese but also with yoghurt and ketchup";
}
Desgin Pattern:
using Creational.Prototype.Model;
namespace Creational.Prototype.DesignPatters;
public abstract class PierogiPrototype
{
public Guid Guid { get; }
public int Count { set; get; }
public string Type { get; set; }
public PierogiPrototype(int count)
{
Guid = Guid.NewGuid();
Count = count;
}
public abstract PierogiPrototype Clone();
public override string ToString()
{
return $"Guid: {Guid}, Count: {Count}, Type: {Type}";
}
}
public class PierogiWithPotatoesAndCheese : PierogiPrototype
{
public PierogiWithPotatoesAndCheese(int count) : base(count)
{
Type = PierogiTypes.WithPotatoesAndCheese;
}
public override PierogiPrototype Clone()
{
return (PierogiPrototype)MemberwiseClone();
}
}
.
.
.
.
.
public class PierogiWithBlueberries : PierogiPrototype
{
public PierogiWithBlueberries(int count) : base(count)
{
Type = PierogiTypes.WithBlueberries;
}
public override PierogiPrototype Clone()
{
return (PierogiPrototype)MemberwiseClone();
}
}
Program:
class Program
{
public static void Main()
{
var firstPortion = new PierogiWithBlueberries(10);
Console.WriteLine(firstPortion);
var secondPortion = firstPortion.Clone();
Console.WriteLine(secondPortion);
firstPortion.Count = 5;
Console.WriteLine(firstPortion);
Console.WriteLine(secondPortion);
}
}
Peter Csala
10.7k1 gold badge16 silver badges36 bronze badges
1 Answer 1
\$\begingroup\$
\$\endgroup\$
2
Problem scope
- The prototype design pattern is usually used whenever you want to minimize the creation time and/or resources of a complex or costly object
- Complex: it has several nested data structures (in other words it is a data rich object)
- Costly: either from time or resource (like CPU or I/O) perspective (like using network/database calls to retrieve initial values)
- According to my understanding none of the above can be said about your derived classes of the
PierogiPrototype
Shallow or Deep copy
- The
MemberwiseClone
method performs a shallow copying which means only the top-level properties are copied over- In case of a complex object you want to copy all the nested structures as well not just their references
- I'm unsure that you are aware of the
ICloneable
interface but it might make sense to take a look at it
Registry or Catalogue
- The prototype pattern can be extended in a way that there is a central place where you store the prototypes and from where you can create copies
- In your case you could store all the variants and create a copy by using the
Type
string
answered Dec 25, 2022 at 20:52
-
1\$\begingroup\$ Thank you for your comment Peter. Its pleasure to meet you again :D. I am making this simple projects as proof of concepts/commemoration exercises. Those might indeed be too simple and exactly fulfill typical use cases. Nevertheless I am more than greateful for your insights. I am fully aware of ICloneable and deep copy/shallow copy mechanisms but in this particular example there is no difference between them. I will keep this one simple and bear in mind the need of deep copy when necessary. Your material to prototype pattern is very interesting, I will make adjustments based on it :D \$\endgroup\$Artur– Artur2022年12月26日 21:25:14 +00:00Commented Dec 26, 2022 at 21:25
-
1\$\begingroup\$ Hi @Artur, nice to meet you again :). I think it is pretty hard to find a simple, yet repsentative prototype candidate. Like I said this pattern should be used against costly or complex objects. If the data structure does not meet either of the criteria then the pattern feels a bit overkill for that problem. \$\endgroup\$Peter Csala– Peter Csala2022年12月27日 06:29:20 +00:00Commented Dec 27, 2022 at 6:29
lang-cs