This post is a extended version of my original post on factory pattern which can be found at http://learn-systemverilog.blogspot.com/2009/08/what-is-factory-pattern.html
If you are working in System Verilog/VMM environment, it is high likely that you will be bombarded with word/expression from OOP world like "Factory Pattern", "Facade Pattern", "Observer Pattern" and so on. There is a finite possibility that you will seat down and start thinking what does those word mean and why they were used too frequently. Let me try to explain the idea/concept behind such word in the simplest way possible.
In SW engineering, a design pattern (or simply pattern) means a general repeatable solution to a commonly occurring problem. Most of these patterns have similarity to something or other in human society and hence they are known by that name.
Factory pattern as the name suggest, is aimed at solving the issue of creation of object. (Factory pattern is not the only pattern to deal with creation of objects, there are a bunch of more patterns for handling different kind of cases, and collectively they are known a creational patterns)
Let me give an example of case where we might need to use creational pattern and how to do so it in SV. Suppose you want to create a "Toy Factory" class which needs to create multiple types of toys (say toy aeroplane, toy tank, toy bus) depending upon the string input to it.
To create these different types of toys we need to have class defined for them. And there will be common method and data interface for these classes, hence it make sense to put all the common data member/task/functions in a class called toy class and then extend it.
class TOY; // Common data memeber string toy_name; // Common methods virtual function string get_type(); endclass : TOY class TOY_Tank extends TOY; function new(); this.toy_name = "Toy Tank"; endfunction : new string function string get_type(); return this.toy_name; endfunction : get_type endclass : TOY_Tank class TOY_Bus extends TOY; function new(); this.toy_name = "Toy Bus"; endfunction : new string function string get_type(); return this.toy_name; endfunction : get_type endclass : TOY_Bus
Now we are done with the bothering about the objects to be created. The next problem that we need to solve is to write the toy factory class itself. For simplicity, let's consider the case where we will want to pass 1 to get an instance of tank class and 2 for getting an instance of bus class from the factory. Now the factory class will look like this.
class TOY_factory; Toy my_toy // Common methods function toy get_toy(string str); if(str == "Toy Tank") this.my_toy = new TOY_Tank(); if(str == "Toy Bus") this.my_toy = new TOY_Bus(); return this.my_toy; endfunction : get_toy endclass : TOY_factory
Note that we are using virtual function for bringing polymorphism in action and save us from having an individual instance of the toy type in the factory class.
- Factory Method Design Pattern from sourcemaking.com
- Factory Method Pattern from wikipedia
- Factory Pattern from JAVA design pattern
Mike Mintz has added the following word of caution/note for this in the thread http://verificationguild.com/modules.php?name=Forums&file=viewtopic&t=3763
The above link is very good. I would just like to add a word of caution. The factory pattern should be rather rare in your architecture. While the choice of where to put the "new" for a class is very important, most of the time (for big components) the answer is in the testbench. That's where all the drivers,generators,monitors, etc should be built.
Also the factory pattern is usually implemented as a function, not a class. When it's a class, you can get sloppy with the necessary parameters and you code is harder to follow.
I understand pretty well the warping of these cautions caused by the three letter methodologies and their misguided quest for generic components, so your usage may have to follow their guidelines. Just remember that (1) in the real world factory patterns are rare, and (2) you do not always have to do it the way the methodology says.