Prototype is a Creational design pattern in which objects are created using a prototypical instance of said object. This pattern is particularly useful for creating lots of instances of an object, all of which share some or all of their values.

The typical way of thinking about this pattern is to consider how we might model the color spectrum. There are something like 10 million visible colors, so modeling them as individual classes (e.g. Red, LightMauve, MacaroniAndCheese, NotYellowButNotGreenEither) would be rather impractical.

However, a color is a color, no matter what color it is; colors have the same kinds of properties as each other even if they don't have the same values for those properties. If we needed to create a lot of color instances, we could do so using the Prototype design pattern.

NOTE: This post is part of a series demonstrating software design patterns using C# and .NET. The patterns are taken from the book Design Patterns by the Gang of Four. Here's the series index page.

The Rundown

  • Type: Creational
  • Useful? 3/5 (Sometimes)
  • Good For: Creating lots of similar objects.
  • Example Code: On GitHub

The Participants

  • The Prototype declares an interface for cloning itself.
  • The ConcretePrototype implements the cloning operation defined in the Prototype.
  • The Client creates a new object by asking the Prototype to clone itself.

A Delicious Example

To demo this pattern, let's think about sandwiches (like we did for Factory Method and Abstract Factory).

A variety of grilled sandwiches, sitting on a countertop

(As you can probably tell, I like sandwiches).

In the picture above, there are many kinds of sandwiches. Just like the color example above, a sandwich is still a sandwich no matter what's between the two slices of bread. Let's demo how we can use the Prototype pattern to build lots of sandwiches.

First, we'll create an abstract class (the Prototype participant) to represent a sandwich, and define a method by which the abstract Sandwich class can clone itself:

/// <summary>
/// The Prototype abstract class
/// </summary>
abstract class SandwichPrototype
    public abstract SandwichPrototype Clone();

Now we need the ConcretePrototype participant class that can clone itself to create more Sandwich instances. For our model, we'll say that a Sandwich consists of four parts: the meat, cheese, bread, and veggies. Here's that class:

class Sandwich : SandwichPrototype
    private string Bread;
    private string Meat;
    private string Cheese;
    private string Veggies;

    public Sandwich(string bread, string meat, string cheese, string veggies)
        Bread = bread;
        Meat = meat;
        Cheese = cheese;
        Veggies = veggies;

    public override SandwichPrototype Clone()
        string ingredientList = GetIngredientList();
        Console.WriteLine("Cloning sandwich with ingredients: {0}", ingredientList.Remove(ingredientList.LastIndexOf(",")));

        return MemberwiseClone() as SandwichPrototype;

    private string GetIngredientList()

class SandwichMenu
    private Dictionary<string, SandwichPrototype> _sandwiches = new Dictionary<string, SandwichPrototype>();

    public SandwichPrototype this[string name]
        get { return _sandwiches[name]; }
        set { _sandwiches.Add(name, value); }

Now we need to create a bunch of sandwiches. In our Main() method (which does double-duty as our Client participant), we can do just that by instantiating the prototype and then cloning it, thereby populating our ``SandwichMenu```:

class Program
    static void Main(string[] args)
        SandwichMenu sandwichMenu = new SandwichMenu();

        // Initialize with default sandwiches
        sandwichMenu["BLT"] = new Sandwich("Wheat", "Bacon", "", "Lettuce, Tomato");
        sandwichMenu["PB&J"] = new Sandwich("White", "", "", "Peanut Butter, Jelly");
        sandwichMenu["Turkey"] = new Sandwich("Rye", "Turkey", "Swiss", "Lettuce, Onion, Tomato");

        // Deli manager adds custom sandwiches
        sandwichMenu["LoadedBLT"] = new Sandwich("Wheat", "Turkey, Bacon", "American", "Lettuce, Tomato, Onion, Olives");
        sandwichMenu["ThreeMeatCombo"] = new Sandwich("Rye", "Turkey, Ham, Salami", "Provolone", "Lettuce, Onion");
        sandwichMenu["Vegetarian"] = new Sandwich("Wheat", "", "", "Lettuce, Onion, Tomato, Olives, Spinach");

        // Now we can clone these sandwiches
        Sandwich sandwich1 = sandwichMenu["BLT"].Clone() as Sandwich;
        Sandwich sandwich2 = sandwichMenu["ThreeMeatCombo"].Clone() as Sandwich;
        Sandwich sandwich3 = sandwichMenu["Vegetarian"].Clone() as Sandwich;

        // Wait for user

By the time we get to the line Console.ReadKey(), how many total separate instances of Sandwich do we have? Nine, six in the sandwichMenu and three initialized as variables sandwich1, sandwich2, sandwich3.

Will I Ever Use This Pattern?

Possibly. It's a good idea if you have the scenario described above. However, I'm not sure how common that scenario is in regular day-to-day coding; I haven't (consciously) implemented this pattern in several years.

The situation in which I see this pattern as being the most useful is when all of the following happens:

  1. You need to create a lot of instances of an object,
  2. AND those instances will be the same or similar as the prototypical instance.
  3. AND creating a new instance of this object would be markedly slower than cloning an existing instance.

If you have all of those conditions, the Prototype design pattern is for you!


The Prototype pattern initializes objects by cloning them from a prototypical instance of said object. It's especially useful when you need to create many instances of related items, each of which could be slightly (but not very) different from the other instances. The primary benefit of this pattern is reduced initialization costs; by cloning many instances from a prototypical instance, you theoretically improve performance.

As always, I like to provide code with my tutorials, so the repository for this pattern is over on GitHub and contains all of the sample code used here.

Happy Coding!