Thanks, Peter, This reply is in three parts: Oops, Ugh and GoF.
FIRST PART: Oops! I am afraid there is a fatal flaw in your reasoning. Your example of the Strategy Pattern is *not* the Strategy Pattern. It is merely two differing implmentations of an interface. The Strategy Pattern is a client based pattern. As the Gang of Four (GoF) in "Design Patterns: Elements of Reusable Object-Oriented Software" said on the inside of the cover: "Strategy (315) Define a family of algorithms encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it." So, your point about the Strategy Pattern, of course, does not work and is a non-starter. A Strategy Pattern most importantly introduces some Helper utility interface for the various implementations of an algorithm. Thus, you could have either A. interface IFormatDatabaseColumnWidth { public void setHelper(Helper helper); public void doWork(); } or B. Inteface IFormatDatabaseColumnWidth { public void doWork(); } But the implementations would have to be something like: public class IFormatDatabaseColumnWidthImpl { private Helper helper; public void setHelper(Helper helper) { this.helper = helper; } public void doWork() { // Do business logic int value = helper.calcColumnWidth(data,metaData[]),columnNo); // Do more business logic } } Thus, there would be a Helper interface: interface Helper { int calcColumnWidth(Object [][] data, MetaData metaData[]) int columnNo); } The differing calculations, then, would go into the Helper interface implementations and not into the IFormatDatabaseColumnWidth interface implementations. So, you might have public class AllRowsFDCW implements Helper { public int calcColumnWidth(Object [][] data, MetaData metaData[]) int columnNo) { // Slowest and most accurate algorithm iterates all rows in the result set } } and public class First100FDCW implements Helper { public int calcColumnWidth(Object [][] data, MetaData metaData[]) int columnNo) { // Algorithm based on the first 100 rows } } and public class class StepwiseFDCW implements Helper { public int calcColumnWidth(Object [][] data, MetaData metaData[]) int columnNo) { // Algorithm that calculates the column width for every N rows } } Please note that the pattern essentially uses polymorphism and late binding not through implementations of an interface but through a composite pattern. Thus, when inversion of control (IoC) is used with the Strategy Pattern, whether you are doing Dependency Injection (DI) or Dependency Lookup (DL), the Helper is what is the subject of the lookup or injection. (IoC, including DL, cannot be identified as DI merely.) Your explanation of the Strategy Pattern leaves out what is essential to the pattern. Consequently, your explanation is merely how Chain of Responsibiltiy (CoR) can be used instead of differing implementations of an interface. See below for a short note on your CoR example. On 6/1/05, Pilgrim, Peter <[EMAIL PROTECTED]> wrote: > Consider a GUI algorithm that displays rows from the database. > The typical problem is to work out the best column width for > rendering the screen. > > interface IFormatDatabaseColumnWidth { > public int calcColumnWidth( Object[][] data, MetaData metaData[], int > columnNo ); > } > > // Slowest and most accurate algorithm iterates all rows in the result set > class AllRowsFDCW implements IFrameDatabaseColumnWidth { ... } > // Algorithm based on the first 100 rows > class First100FDCW implements IFrameDatabaseColumnWidth { ... } > // Algorithm that calculates the column width for every N rows > class StepwiseFDCW implements IFrameDatabaseColumnWidth { ... } > > This is the classic strategy pattern, as I remember writing it in a Swing/JDBC > five years ago. (In fact Xenon-SQL is still out there somewhere, but it > is broken against JDK 1.3 and 24/7/365 the time to fix it! ) SECOND PART: Ugh! In my opinion, by the way, as an aside, using the CoR to replace mere implementations of an interface would be rather *nuts*. This would merely obfuscate and provide no benefit at all. This is what our fellow traveler Frank Zammettie finds inherently suspicious about the *OOP nuts*. This is, I am afraid, similar to some of the rather *knee jerk* uses of CoR floating around. How does that old saw go? A boy with a new hammer sees the whole world as a nail? THIRD PART: GoF The GoF used as their signal example a Composition class which traversed and repaired (traverse(), repair()) and, much like your algorithms with result sets, employed a field utility class Compositor with the method compose() to implement various linebreaking strategies (SimpleCompositor, TeXCompositor, and ArrayCompositor). According to the GoF, who defined these things, the Strategy Pattern must contain: A Context interface holding a Strategy (which I called a "Helper") interface that has varying ConcreteStrategy implementations holding the optional algorithms (strategies). Indeed, they suggested that you might use inheritance to factor out the common factors in the ConcreteStragey (Helper implementation) classes. Let me be clear about something, as Richard Nixon said. The Strategy Pattern is used to eliminate conditional statements, among other things. So, if you are merely saying that CoR can also be used for this, then that is clearly true. Lots of patterns can be used for that, including the questionable Template Method Pattern. That does not make the patterns equivalent. I am not saying that you are saying that does make them equivalent. I am just saying that we need to make sure we are not making that mistake. Anyway, your example does not work because you understanding here of the Strategy Pattern is flawed. No? > > You can rewrite the above strategy with Chain of Responsibility > pedantically. If you have a very functional requirement for it. > > class ChainFDCW implements IFrameDatabaseColumnWidth { > > Catalog catalog; > String commandName; > > // IoC container friendly > public void setCatalog( catalog ) { ... } > public void setCommandName( name ) { ... } > > public int calcColumnWidth( Object[][] data, MetaData metaData[], int > columnNo ) > { > Context context = new FDCWContext( data, metaData, columnNo ); > Command command = catalog.getCommand( commandName ); > command.execute( context ); > if ( context.isCalculatedOk() ) > return context.getColumnWidth(); > else > throw new StrategyRuntimeException( > "Failed to calculate column width" ); > } > } > > Ok writing a CoR for calculating data width takes a bit of stretching > the imagination, but of course you can do it, which is the point. -- "You can lead a horse to water but you cannot make it float on its back." ~Dakota Jack~ --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]