|
-
July 23rd, 2010, 12:07 AM
#1
how to comprehend the definition of Bridge pattern by Gof?
1.There is an object varying for two dimensionality which change commonly.we can decouple the two dimensionality ,so they can vary indepently and not mutually affect.For example ,when we want to draw a picture through pen.Pen may have different size like big pen or small pen.It also has different color like red or green.Apperently the pen as an object used to draw will vary through different matching of size and color.Now,we can utilize a "bridge" to connect the CSize class and CColor class.is it that?
abstract class Brush
2 {
3 protected Color c;
4 public abstract void Paint();
5
6 public void SetColor(Color c)
7 { this.c = c; }
8 }
1 class BigBrush : Brush
2 {
3 public override void Paint()
4 { Console.WriteLine("Using big brush and color {0} painting", c.color); }
5 }
1 class SmallBrush : Brush
2 {
3 public override void Paint()
4 { Console.WriteLine("Using small brush and color {0} painting", c.color); }
5 }
1 class Color
2 {
3 public string color;
4 }
1 class Red : Color
2 {
3 public Red()
4 { this.color = "red"; }
5 }
1 class Green : Color
2 {
3 public Green()
4 { this.color = "green"; }
5 }
1 class Blue : Color
2 {
3 public Blue()
4 { this.color = "blue"; }
5 }
1 class Program
2 {
3 public static void Main()
4 {
5 Brush b = new BigBrush();
6 b.SetColor(new Red());
7 b.Paint();
8 b.SetColor(new Blue());
9 b.Paint();
10 b.SetColor(new Green());
11 b.Paint();
12
13 b = new SmallBrush();
14 b.SetColor(new Red());
15 b.Paint();
16 b.SetColor(new Blue());
17 b.Paint();
18 b.SetColor(new Green());
19 b.Paint();
20 }
2.Gof defines the bridge pattern as Decouple an abstraction from its implementation so that the two can vary independently.
-
July 23rd, 2010, 04:50 AM
#2
Re: how to comprehend the definition of Bridge pattern by Gof?
No, this doesn't seem right. As you said, the Bridge is used to decouple an abstraction from its implementation so that the two can vary independently; you, however, should have a simple composition of 2 classes here.
Maybe the word "vary" introduced some confusion? In the explanation of the pattern, it means "utilize a different approach". This can be done at runtime, and you can add/change the concrete Abstraction or concrete Implementor independently at design time.
There's no such an abstraction in your case. You just have two classes representing two different concepts, that should be in the composition relationship with a concrete Brush, as if to configure it. So there's no reason to fear these classes (CSize & CColor) will affect each other.
Also, IMO, you're overusing inheritance here. The concepts (classes) are to fine-grained. There's really no need to derive BigBrush and SmallBrush from Brush, because you can define the size and color in the constructor or via some Set-functions. (Even worse, imagine someone created subclasses such are RedBrush, GreenBrush, MagentaBrush...) It would be OK to have specializations like SolidBrush or TextureBrush, though.
So, this is not the case where you could apply the Bridge pattern. But, I'd suggest some refactoring.
Last edited by TheGreatCthulhu; July 23rd, 2010 at 04:56 AM.
-
July 23rd, 2010, 05:19 AM
#3
Re: how to comprehend the definition of Bridge pattern by Gof?
P.S. The Bridge pattern would be if you had:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
abstact Brush (the Abstraction)
<----- SolidBrush // solid-brush-specific code
<----- PatternBrush // pattern-brush-specific code ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
(Brush references BrushImplementor)
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
abstact BrushImplementor
<----- RGBBrushImplementor // rgb-model-specific code
<----- CYMKBrushImplementor // cymk-model-specific code ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Now, this is not exactly a real world model, but it should give you an idea (i just couldn't come up with anything more appropriate at the moment).
Don't take this as a recommendation for your design - it's just me trying to explain Bridge to you.
In the context of the Bridge pattern, the word "abstraction" doesn't mean "abstract class". It means "abstraction of a concept", as opposed to implementation of what that abstraction does and how it does it.
Here "abstraction" is represented by Brush, but also by SolidBrush and by PatternBrush.
Here's another (again ad hoc) example to illustrate the point:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
abstact PieChart (the Abstraction)
<----- AnotatedPieChart
<----- StandardPieChart ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
(PieChart references ChartImplementor)
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
abstact ChartImplementor
<----- DirectXChartImplementor
<----- OpenGLChartImplementor
<----- GDIChartImplementor ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Last edited by TheGreatCthulhu; July 23rd, 2010 at 05:28 AM.
-
July 23rd, 2010, 08:16 AM
#4
Re: how to comprehend the definition of Bridge pattern by Gof?
 Originally Posted by TheGreatCthulhu
P.S. The Bridge pattern would be if you had:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
abstact Brush (the Abstraction)
<----- SolidBrush // solid-brush-specific code
<----- PatternBrush // pattern-brush-specific code ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
(Brush references BrushImplementor)
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
abstact BrushImplementor
<----- RGBBrushImplementor // rgb-model-specific code
<----- CYMKBrushImplementor // cymk-model-specific code ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Now, this is not exactly a real world model, but it should give you an idea (i just couldn't come up with anything more appropriate at the moment).
Don't take this as a recommendation for your design - it's just me trying to explain Bridge to you.
In the context of the Bridge pattern, the word "abstraction" doesn't mean "abstract class". It means "abstraction of a concept", as opposed to implementation of what that abstraction does and how it does it.
Here "abstraction" is represented by Brush, but also by SolidBrush and by PatternBrush.
Here's another (again ad hoc) example to illustrate the point:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
abstact PieChart (the Abstraction)
<----- AnotatedPieChart
<----- StandardPieChart ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
(PieChart references ChartImplementor)
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
abstact ChartImplementor
<----- DirectXChartImplementor
<----- OpenGLChartImplementor
<----- GDIChartImplementor ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I refactor the first sample you have given as follow:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
abstact Brush (the Abstraction)
<----- RGBBrush // RGB-brush-specific code
<----- CYMKBrush // CYMK-brush-specific code
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
(Brush references BrushImplementor)
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
abstact BrushImplementor
<----- SolidBrushImplementor // Solid-model-specific code
<----- PatternBrushImplementor // Pattern-model-specific code
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I make the transposition , so is it appropriate?
I can not distinguish the logic that which characteristic of the brush should be divided into Abstract , the "Solid" or the "RGB"? could any one be specialized as abstract subclass?
-
July 23rd, 2010, 10:14 AM
#5
Re: how to comprehend the definition of Bridge pattern by Gof?
Yeah. Maybe it's even better that way. As I said, that example with the brushes is probably not the best one, but I wanted something you can relate to.
The thing is, something like Brush is generally speaking not complex enough to allow for a meaningful application of the Bridge pattern.
Patterns can be somewhat confusing because they are abstract concepts, applicable not only in a specific situation, but to a set of related problems - and that's what makes them so powerful.
Anyway, you ask how to distinguish between what features are considered part of the "abstraction"-classes, and what are considered part of the "implementor"-classes.
This depends on the specific problem, and on the specific design. You think about the problem and design the system, and after several iterations of this, you come up with something that seems right. I'll try to make more clear, since I understand that the terminology used can introduce some confusion.
The "abstraction"-classes all inherit from a base class. This class defines a set of methods that are common to all derived "abstractions". These methods can be divided in 2 groups:
1) methods actually implemented (or configured) by the "implementor"-classes (these are not virtual)
2) methods specific to "abstraction"-classes (these may be virtual)
The methods in group (1) are common to all "abstraction"-classes, and their behavior can be configured with a different instance of an Implementor-derived class.
This way, the implementation is itself abstracted, and is separated from the abstraction.
The methods defining the behavior that doesn't need to be configured in such a way, or that you don't expect to change that often can go in (2).
The group (2) also contains virtual "abstraction"-specific methods that are meant to be overridden.
So, you decide what kind of behavior is common to all the "abstraction"-classes, and if this behavior either needs to be dynamically configured, or is expected to support new requirements in the future, you move it's implementation to "implementor"-classes. This way, the applications already using your "abstraction"-classes can take advantage of new functionality without the need to recompile them.
Tale a look at the slightly modified GoF intro example:
Say you have an abstract class Window, and derived classes
DirectXWindow, OpenGlWindow, GDIWindow.
All works fine, but now, suddenly, you're required to create a new kind of a window, but here "new kind" doesn't mean "new graphics API", but new behavior. Suddenly, different criteria come into play. This "new kind" is IconWindow.
So, without Bridge, you derive IconWindow from Window, and then, in turn, derive DirectXIconWindow, OpenGlIconWindow, GDIIconWindow from IconWindow.
It's a mess, right?
With Bridge, you say: OK, now I have RegularWindow and IconWindow, and what's common to these are the drawing routines, which can be implemented in any of the different graphics APIs. In this case, Window, RegularWindow and IconWindow are "abstraction"-classes. The drawing routines will just call (and maybe pass some parameters to) the corresponding methods of WindowImp abstract class, the root of the "implementor"-hierarchy. Now you'd have DirectWindowImp, OpenGlWindowImp, GDIWindowImp derive from that.
So, now you've separated two aspects of the same object into two connected ("bridged") hierarchies of classes. It's like you've classified these concepts on the basis of two different sets of classification criteria.
Again, IMO, there's no need to apply this pattern to Brush.
Last edited by TheGreatCthulhu; July 23rd, 2010 at 10:17 AM.
-
July 23rd, 2010, 10:20 PM
#6
Re: how to comprehend the definition of Bridge pattern by Gof?
very detailed exposition!upstairs friend deeply comprehend the design pattern.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|