In a project that I\'ve been involved with for many years, I\'ve gradually evolved a design pattern that\'s proven to be extremely useful for me. I sometimes feel I should
It sounds a bit like Service Locator, in which your featherweights are registered as singletons.
Believe me or not. I was thinking the very same thing this morning.
I have used this pattern before but I've never found a reference for it nor know how to name it.
I think is a kind of "Keyed" singleton, where the instances are stored somewhere and they are obtained using a key.
The last time I use it was to retrieve data from different sources.
I had about 50 database tables ( make it 10 ) And I have a front end "table" where the data was to be displayed, but the data could come from any of those sources and each one require different logic ( queries, joins, keys, etc. )
This front end was "configurable" so I couldn't know what values were to be shown and which other won't.
The solution was to take the columnName ( in the front end ) as the key, and get the correct instance to create the right query.
This was installed in a hash map at the beginning and later retrieved from a database table.
The code was like this:
class DataFetcher {
abstract Object getData( Object id );
}
class CustomerNameDataFetcher extends DataFetcher {
Object getData( Object customerId ) {
// select name from customer where id = ?
}
}
class CompanyAdressDataFetcher extends DataFetcher {
Object getData( Object customerId ) { // don't ask why.
// select name from company , customer where customer.co = company.co and cu = ? etc.
}
}
class ProductColor extends DataFetcher {
Object getData( Object x ) {
// join from customer to color, to company to season to a bunch of table where id = ?
}
// And the list goes on.
Each subclass used different logic.
At runtime the user configured it's view, and select what he want to see.
When the user selected the columns to see, I used the column name and an Id to fetch the data.
The DataFetchers were all installed in the parent class ( I didn't want to have a separeate class for this ) in a class method.
class DataFetcher {
abstract Object getData( Object id );
private static final Map fetchers = new HashMap();static {
fetchers.put("customer.name", new CustomerNameDataFetcher() );
fetchers.put("company.address", new CompanyAdressDataFetcher () );
fetchers.put("product.color", new ProductColor () );
...
}
public static DataFetcher getFetcher( String id ) {
return fetchers.get( id );
}
}
At the end to fill the front end table I just call it like this:
pseudocode
for each row in table
for each column in row
column.text = DataFetcher.getFetcher( column.id ).getData( row.id )
end
end
Is it like this? Or do I misread your description and mine is quite different.
Finally I think this is called SingletonRegistry or something like that. I ( probably ) like you, created this out of necessity. Chances are this is a common pattern.
What you have is a map, aka Dictionary. You just have a unique twist on it by having multiple keys map to one object.
Why its a map:
You can find implementations in:
It sounds like a variety of a Flyweight (many cars share a WankelEngine). But how does that make sense? Most cars have an engine, but how can many of them have the same instance of an Engine? They wouldn't get far that way. Or do you mean that many cars have an Engine of type WankelEngine? Spose that makes more sense. Then what's the use of the "WankelEngine definition object"? Is it a Factory that's building flavors of that object and passing them back to the requestor? If so it doesn't sound like a definition object, sounds more like a Factory that's taking in the parameters of the object to build and giving that object back.
I do see some good GoF practices in here, specifically that you are composing instead of inheriting (my Car has an Engine vs. my Car's Engine is a WankelEngine). I wish I could recall the quote exactly, but it's something like "inheritance breaks encapsulation" and "favor composition over inheritance".
I'm curious what problem is solved by this. I think you've added a good deal of complexity and I'm not seeing the need for such complexity. Maybe it's something specific to your language that I don't understand.
The GoF guys do discuss composing patterns into larger patterns, MVC in particular is an aggregate of three other patterns. Sounds like you've done something like that.
Sounds like a combination of GoF Builder, Prototype, and maybe Featherweight to me.
I've used a pattern similar to this before, most often in games. I'd have a WeaponDefinition and WeaponInstance classes (not quite with those names). The WeaponDefinition class (and various subclasses, if I have different types of weapons, e.g. melee vs projectile) would be responsible for keeping track of the global data for that type of weapon (rate of fire, max ammo, name, etc) and has all the logic. The WeaponInstance class (and subclasses) contain the current state in the firing sequence (for use with comparing the rate of fire), the current ammo count, and a pointer (it could be some key into a manager class as in your example, but that doesn't seem to be a requirement of the pattern) to the WeaponDefinition. The WeaponInstance has a bunch of functions for firing, reloading, etc, that just call the appropriate method on the WeaponDefinition instance, passing itself as an argument. This means the WeaponDefinition stuff isn't dupicated for every tank/soldier/airplane in the game world, but they all have their own ammo counts, etc.
I have no idea what it's called, and I'm not sure it's quite the same as what you're talking about, but I think it's close. It's definitely useful.