Monday, March 29, 2010

Factory Patterns

In my book I covered two kinds of factory patterns, the Abstract Factory Pattern, and the Factory Method Pattern. Both are used to decouple concrete class creation from the objects that depend on them. Let's say I have a company and the company has a Department class. And in this company, each department has one of three job types: full-time, part-time, and contractor. I could have a method in the Department class like create_job(job_type)that takes a type and goes through a switch statement and coughs out a concrete job class.

Or, I could do something that will let me easily extend my Department with new job types in the future and apply the Factory Method Pattern. In this case, I make Department an abstract class, and create concrete classes called FullTimeDepartment, PartTimeDepartment, and ContractorDepartment. Each one will implement create_job() in their own way to return the appropriate job for that department. This rocks because now I can do something like:
my_department = FullTimeDepartment.new
job = my_department.create_job() #this returns a full time job!

Later, I can add a new department, the FullTimeButOnlyShowUpToWorkOnDaysThatDontEndInYDepartment without changing any existing code. I would then call .fire(:all) on that particular department, but we're making jobs here. So that's the Factory Method Pattern.

The other pattern is great for when you need to create families of stuff. Let's say you need a system for ordering office supplies for your department, things like staplers, paper clips, ink, and post-it notes. In most departments, a stapler can be just a standard black stapler. But those tricksters in the IT department love them some red Swingline staplers for some crazy reason. Here's a great time to use the Abstract Factory Pattern. In this case, each Department will have a OfficeSupplyFactory. Now both the Department and the OfficeSupplyFactory are abstract, and each concrete implementation of Department will specify which concrete OfficeSupplyFactory it will use. For instance, our BoringBusinessDepertment might use the PlainOfficeSupplyFactory, but the HipCoolWebDepartment will certainly be using the StuffWeSawInTheMoviesSupplyFactory.

Clear as mud right? Don't worry, basically the idea is that when you go to instantiate a concrete class in one of your objects, consider using a Factory Pattern of some sort.

No comments: