Which pattern does this conform to?
From: Jimmy Cerra (jfcst24_public_at_yahoo.com)
Date: 01/17/05
- Previous message: Isaac Gouy: "Re: up front designs always useless"
- Next in thread: Andrew McDonagh: "Re: Which pattern does this conform to?"
- Reply: Andrew McDonagh: "Re: Which pattern does this conform to?"
- Reply: Daniel T.: "Re: Which pattern does this conform to?"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Mon, 17 Jan 2005 20:01:20 GMT
Hi. I've been struggling lately while designing a framework [1, 2], so
I examined some existing solutions. I noticed a bunch of frameworks
organized in the following fashion, so I'm wondering if it is a specific
pattern.
The problem is that using an abstract factory to build families of
related objects is awkward when those objects depend on their own
family's types rather than their base types. This could violate the
Liskov Substitution Principle [1]. For instance, consider the abstract
toolkit:
] package AbstractWidgets;
] interface AbstractFactory {
] Window getWindow();
] Button getButton();
] ...
] }
] interface Window {
] void add(Button bb);
] ...
] }
] interface Button {...}
Two different implementations may not have compatible look-and-feels
(i.e. Motif vs. WindowsXP based) or depend on incompatible drawing
libraries (i.e. GTK vs. QT based). However, a client could still
associate these two implementations:
] Window ww = aGtkBasedToolkit.getWindow();
] Button bb = aQtBasedToolkit.getButton();
] ww.add(bb);
That's not good. It seems to be especially hard to prevent these kinds
of mistakes in languages without built-in templates or generics.
The problem seems to have been avoided in some frameworks by making the
dependent objects responsible for creating their dependencies:
] package AbstractWidgets;
] interface AbstractFactory {
] Window getWindow();
] ...
] }
] interface Window {
] Button createButton();
] ...
] }
] interface Button {...}
Now the implementations are free to define their own quirks without
violating the LSP:
] package GtkWidgets;
] import AbstractWidgets.*;
] class GtkBasedToolkit implements AbstractFactory {
] Window getWindow() {
] return new GtkWindow;
] }
] ...
] }
] class GtkWindow implements Window {
] private static GtkLib gg = new GtkLib();
] Button createButton() {
] return new GtkButton(gg);
] }
] ...
] }
] class GtkButton implements Button {
] protected Button(GtkLib gg) {...}
] ...
] }
Clients then use them like this:
] Window ww = aGtkBasedToolkit.getWindow();
] Button bb = ww.createButton();
Disadvantages (that I can see) of this design include:
* It is hard to change the framework to support new Objects.
* It may violate the single responsibility principle, since classes are
responsible for their behavior and creating other objects.
One example of the pattern is the Document Object in the W3C's DOM. You
create it's components with the instance rather than the Builder that
creates the Document Object:
] Document dd = aDocumentBuilder.parse(file);
] Element ee = dd.createElement(tagName);
] // use ee
Another example is in JDBC. To create a statement to query a databse,
one uses a Connection rather than a DriverManager object:
] Connection cc = DriverManager.getConnection(urlString);
] Statement ss = cc.createStatement();
] ResultSet rr = ss.executeQuery(sqlString);
Is there a name for this pattern? Am I misinterpreting a classic
pattern in these cases?
-- Jimmy Cerra https://nemo.dev.java.net [1] http://groups-beta.google.com/group/comp.object/ browse_frm/thread/cf00bdcc47966776/e7685d427e30a5f1 [2] http://groups-beta.google.com/group/comp.object/ browse_frm/thread/aec14c5f186e804e/e5032a71e0cce334
- Previous message: Isaac Gouy: "Re: up front designs always useless"
- Next in thread: Andrew McDonagh: "Re: Which pattern does this conform to?"
- Reply: Andrew McDonagh: "Re: Which pattern does this conform to?"
- Reply: Daniel T.: "Re: Which pattern does this conform to?"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|