Bridge pattern? What is the use?

A

Adrian

The code below was taken from an example.
All the "noise" in the example was thrown out.
This is supposedly according to the bridge
pattern. What in the code (which lines)
represent the bridge pattern (make this code
to be according to the bridge pattern),
and what is the advantage of employing the
bridge pattern? It seems "l'art pour l'art" to me.

Adrian

using System.Collections;

namespace trial_seven
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
Customers customers = new Customers("Chicago");
customers.Data = new CustomersData();
customers.show();
customers.show();
}

class CustomersBase
{
private DataObject dataObject;
protected string group;
public CustomersBase(string group)
{
this.group = group;
}

public DataObject Data
{
set
{
dataObject = value;
}
get
{
return dataObject;
}
}

public virtual void show()
{
dataObject.ShowRecord();
}
}

class Customers:CustomersBase
{
public Customers (string group):base(group)
{
}
}

abstract class DataObject
{
public abstract void ShowRecord();
}

class CustomersData:DataObject
{
private ArrayList customers = new ArrayList();
private static int current = 0;

public CustomersData()
{
customers.Add("Jim Jones");
customers.Add("Frank Rapper");
}
public override void ShowRecord()
{
Console.WriteLine(customers[current++]);
}
}
}
}
 
A

Adrian

Chris Fulstow said:
l'art pour decoupler une abstraction de son execution ;)
http://en.wikipedia.org/wiki/Bridge_pattern
Yes that is where I got it from :(

"decoupler une abstraction de son execution"
That is happening twice in my perception,
but that doesn't seem to be specific for
what the code is purporting to represent,
namely a bridge. I could image show, called
in main, and, in turn, calling ShowRecord, to
be the bridge. But what is so useful about
doing that? Obfuscation or 3-tier stuff?
 
D

Dave Sexton

Hi Adrian,

Maybe this link will clear it up more for you:

G.O.F. on Bridge:
http://www.dofactory.com/Patterns/PatternBridge.aspx


I believe you have partially identified the bridge. The part that you didn't acknowledge is the two abstract classes and the
decoupling of the implementation.

The GOF example is much clearer, IMO. Look at the C# code sample.

To equate their sample to your sample:

[STAThread]
static void Main(string[] args)
{
Customers customers = new Customers("Chicago");
customers.Data = new CustomersData();
customers.show();

customers.Data = new PrimaryCustomersData();
customers.show();

customers.Data = new SpecialProcessCustomersData();
customers.show();
}


Also, note that show can call multiple methods on the Data object if necessary, so it doesn't have to simply be pass-thru as in
these examples. In that case the concrete CustomerBase implementation acts as a facade as well. Also, concrete CustomerBase
implementations would commonly have different, higher-level methods than the associated Data object.

Its useage might be even clearer if you look at a method that takes a parameter of type, "CustomerBase". In that case the benefit
of both the abstraction and decoupling of implementation is more apparent:

public void ShowCustomerToUser(CustomerBase customer)
{
customer.show();
}

HTH
 
A

Adrian

Is using abstract and concrete classes (decoupling)
for hiding the concrete classes from users? If not,
why is it done?



Dave Sexton said:
Hi Adrian,

Maybe this link will clear it up more for you:

G.O.F. on Bridge:
http://www.dofactory.com/Patterns/PatternBridge.aspx


I believe you have partially identified the bridge. The part that you
didn't acknowledge is the two abstract classes and the
decoupling of the implementation.

The GOF example is much clearer, IMO. Look at the C# code sample.

To equate their sample to your sample:

[STAThread]
static void Main(string[] args)
{
Customers customers = new Customers("Chicago");
customers.Data = new CustomersData();
customers.show();

customers.Data = new PrimaryCustomersData();
customers.show();

customers.Data = new SpecialProcessCustomersData();
customers.show();
}


Also, note that show can call multiple methods on the Data object if
necessary, so it doesn't have to simply be pass-thru as in
these examples. In that case the concrete CustomerBase implementation
acts as a facade as well. Also, concrete CustomerBase
implementations would commonly have different, higher-level methods than the associated Data object.

Its useage might be even clearer if you look at a method that takes a
parameter of type, "CustomerBase". In that case the benefit
 
D

Dave Sexton

Hi Adrian,

Exactly. By using an abstract class you can swap out the implementation in the caller whenever you need to refactor your code and
it enables your code to be dynamic enough when you need to vary implementations at runtime. The consumer of the class doesn't need
to be aware of the implemention, it just needs a reference to the interface (abstract class in this case).

Be aware when using patterns that decouple implemention by using polymorphism that if you see something like the following you
should probably invest your time in finding a more appropriate pattern to meet your needs:

public void ShowCustomerToUser(CustomerBase customer)
{
if (customer.GetType() == typeof(SpecialProcessCustomerData))
{
// we require a special process to occur first, in this case
customer.SpecialProcess();
}

// all customers may be "shown"
customer.show();
}

Hopefully you see the benefit of the bridge pattern and how it could be used to alleviate any need for the explicit Type check
above. The idea is to "abstract" the "ShowCustomerToUser" method from requiring a reference or any knowledge at all of the
implementation of the specified "customer" object.

public class SpecialProcessCustomerData : DataObject
{
public void show()
{
// TODO: special processing
// TODO: show something
}
}

--
Dave Sexton

Adrian said:
Is using abstract and concrete classes (decoupling)
for hiding the concrete classes from users? If not,
why is it done?



Dave Sexton said:
Hi Adrian,

Maybe this link will clear it up more for you:

G.O.F. on Bridge:
http://www.dofactory.com/Patterns/PatternBridge.aspx


I believe you have partially identified the bridge. The part that you
didn't acknowledge is the two abstract classes and the
decoupling of the implementation.

The GOF example is much clearer, IMO. Look at the C# code sample.

To equate their sample to your sample:

[STAThread]
static void Main(string[] args)
{
Customers customers = new Customers("Chicago");
customers.Data = new CustomersData();
customers.show();

customers.Data = new PrimaryCustomersData();
customers.show();

customers.Data = new SpecialProcessCustomersData();
customers.show();
}


Also, note that show can call multiple methods on the Data object if
necessary, so it doesn't have to simply be pass-thru as in
these examples. In that case the concrete CustomerBase implementation
acts as a facade as well. Also, concrete CustomerBase
implementations would commonly have different, higher-level methods than the associated Data object.

Its useage might be even clearer if you look at a method that takes a
parameter of type, "CustomerBase". In that case the benefit
 
A

Adrian

In case of: / if you do as you suggest:
customers.Data = new PrimaryCustomersData();
customers.show();

customers[] isn't filled
and the appp errors out



Dave Sexton said:
Hi Adrian,

Maybe this link will clear it up more for you:

G.O.F. on Bridge:
http://www.dofactory.com/Patterns/PatternBridge.aspx


I believe you have partially identified the bridge. The part that you
didn't acknowledge is the two abstract classes and the
decoupling of the implementation.

The GOF example is much clearer, IMO. Look at the C# code sample.

To equate their sample to your sample:

[STAThread]
static void Main(string[] args)
{
Customers customers = new Customers("Chicago");
customers.Data = new CustomersData();
customers.show();

customers.Data = new PrimaryCustomersData();
customers.show();

customers.Data = new SpecialProcessCustomersData();
customers.show();
}


Also, note that show can call multiple methods on the Data object if
necessary, so it doesn't have to simply be pass-thru as in
these examples. In that case the concrete CustomerBase implementation
acts as a facade as well. Also, concrete CustomerBase
implementations would commonly have different, higher-level methods than the associated Data object.

Its useage might be even clearer if you look at a method that takes a
parameter of type, "CustomerBase". In that case the benefit
 
A

Adrian

By the way I did add on another child of DataObject.

Adrian said:
In case of: / if you do as you suggest:
customers.Data = new PrimaryCustomersData();
customers.show();

customers[] isn't filled
and the appp errors out



Dave Sexton said:
Hi Adrian,

Maybe this link will clear it up more for you:

G.O.F. on Bridge:
http://www.dofactory.com/Patterns/PatternBridge.aspx


I believe you have partially identified the bridge. The part that you
didn't acknowledge is the two abstract classes and the
decoupling of the implementation.

The GOF example is much clearer, IMO. Look at the C# code sample.

To equate their sample to your sample:

[STAThread]
static void Main(string[] args)
{
Customers customers = new Customers("Chicago");
customers.Data = new CustomersData();
customers.show();

customers.Data = new PrimaryCustomersData();
customers.show();

customers.Data = new SpecialProcessCustomersData();
customers.show();
}


Also, note that show can call multiple methods on the Data object if
necessary, so it doesn't have to simply be pass-thru as in
these examples. In that case the concrete CustomerBase implementation
acts as a facade as well. Also, concrete CustomerBase
implementations would commonly have different, higher-level methods than the associated Data object.

Its useage might be even clearer if you look at a method that takes a
parameter of type, "CustomerBase". In that case the benefit
 
D

Dave Sexton

Hi Adrian,

I'm not sure I understand what you mean. The app won't even compile because the PrimaryCustomersData class isn't defined. I was
just trying to illustrate a point: Being able to assign any implementation to the Data property is part of the flexibility provided
by the bridge pattern.

If you tried to compile the application after creating your own PrimaryCustomersData class then it's your implementation that is
failing.

Care to post your code?

--
Dave Sexton

Adrian said:
In case of: / if you do as you suggest:
customers.Data = new PrimaryCustomersData();
customers.show();

customers[] isn't filled
and the appp errors out



Dave Sexton said:
Hi Adrian,

Maybe this link will clear it up more for you:

G.O.F. on Bridge:
http://www.dofactory.com/Patterns/PatternBridge.aspx


I believe you have partially identified the bridge. The part that you
didn't acknowledge is the two abstract classes and the
decoupling of the implementation.

The GOF example is much clearer, IMO. Look at the C# code sample.

To equate their sample to your sample:

[STAThread]
static void Main(string[] args)
{
Customers customers = new Customers("Chicago");
customers.Data = new CustomersData();
customers.show();

customers.Data = new PrimaryCustomersData();
customers.show();

customers.Data = new SpecialProcessCustomersData();
customers.show();
}


Also, note that show can call multiple methods on the Data object if
necessary, so it doesn't have to simply be pass-thru as in
these examples. In that case the concrete CustomerBase implementation
acts as a facade as well. Also, concrete CustomerBase
implementations would commonly have different, higher-level methods than the associated Data object.

Its useage might be even clearer if you look at a method that takes a
parameter of type, "CustomerBase". In that case the benefit
 
A

Adrian

Dave, I can see what you are getting at here. How the bridge pattern does a
better job
then polymorphism.

I have successfully implemented your suggestions to bear out the workings of
the example a bit better now.

Your remarks do a good job in explaining the know-why of the bridge pattern.

Unfortunately too often *only* know-how and know-when is explained.

Many thanks,
Adrian. (Nom de plume.)

Dave Sexton said:
Hi Adrian,

Exactly. By using an abstract class you can swap out the implementation
in the caller whenever you need to refactor your code and
it enables your code to be dynamic enough when you need to vary
implementations at runtime. The consumer of the class doesn't need
to be aware of the implemention, it just needs a reference to the
interface (abstract class in this case).
Be aware when using patterns that decouple implemention by using
polymorphism that if you see something like the following you
should probably invest your time in finding a more appropriate pattern to meet your needs:

public void ShowCustomerToUser(CustomerBase customer)
{
if (customer.GetType() == typeof(SpecialProcessCustomerData))
{
// we require a special process to occur first, in this case
customer.SpecialProcess();
}

// all customers may be "shown"
customer.show();
}

Hopefully you see the benefit of the bridge pattern and how it could be
used to alleviate any need for the explicit Type check
above. The idea is to "abstract" the "ShowCustomerToUser" method from
requiring a reference or any knowledge at all of the
implementation of the specified "customer" object.

public class SpecialProcessCustomerData : DataObject
{
public void show()
{
// TODO: special processing
// TODO: show something
}
}

--
Dave Sexton

Is using abstract and concrete classes (decoupling)
for hiding the concrete classes from users? If not,
why is it done?



Dave Sexton said:
Hi Adrian,

Maybe this link will clear it up more for you:

G.O.F. on Bridge:
http://www.dofactory.com/Patterns/PatternBridge.aspx


I believe you have partially identified the bridge. The part that you
didn't acknowledge is the two abstract classes and the
decoupling of the implementation.

The GOF example is much clearer, IMO. Look at the C# code sample.

To equate their sample to your sample:

[STAThread]
static void Main(string[] args)
{
Customers customers = new Customers("Chicago");
customers.Data = new CustomersData();
customers.show();

customers.Data = new PrimaryCustomersData();
customers.show();

customers.Data = new SpecialProcessCustomersData();
customers.show();
}


Also, note that show can call multiple methods on the Data object if
necessary, so it doesn't have to simply be pass-thru as in
these examples. In that case the concrete CustomerBase implementation
acts as a facade as well. Also, concrete CustomerBase
implementations would commonly have different, higher-level methods
than
the associated Data object.
Its useage might be even clearer if you look at a method that takes a
parameter of type, "CustomerBase". In that case the benefit
of both the abstraction and decoupling of implementation is more apparent:

public void ShowCustomerToUser(CustomerBase customer)
{
customer.show();
}

HTH

--
Dave Sexton

l'art pour decoupler une abstraction de son execution ;)
http://en.wikipedia.org/wiki/Bridge_pattern

Yes that is where I got it from :(

"decoupler une abstraction de son execution"
That is happening twice in my perception,
but that doesn't seem to be specific for
what the code is purporting to represent,
namely a bridge. I could image show, called
in main, and, in turn, calling ShowRecord, to
be the bridge. But what is so useful about
doing that? Obfuscation or 3-tier stuff?
 
A

Adrian

Dave, please see my other post to you.
Many thanks.



Dave Sexton said:
Hi Adrian,

I'm not sure I understand what you mean. The app won't even compile
because the PrimaryCustomersData class isn't defined. I was
just trying to illustrate a point: Being able to assign any
implementation to the Data property is part of the flexibility provided
by the bridge pattern.

If you tried to compile the application after creating your own
PrimaryCustomersData class then it's your implementation that is
failing.

Care to post your code?

--
Dave Sexton

In case of: / if you do as you suggest:
customers.Data = new PrimaryCustomersData();
customers.show();

customers[] isn't filled
and the appp errors out



Dave Sexton said:
Hi Adrian,

Maybe this link will clear it up more for you:

G.O.F. on Bridge:
http://www.dofactory.com/Patterns/PatternBridge.aspx


I believe you have partially identified the bridge. The part that you
didn't acknowledge is the two abstract classes and the
decoupling of the implementation.

The GOF example is much clearer, IMO. Look at the C# code sample.

To equate their sample to your sample:

[STAThread]
static void Main(string[] args)
{
Customers customers = new Customers("Chicago");
customers.Data = new CustomersData();
customers.show();

customers.Data = new PrimaryCustomersData();
customers.show();

customers.Data = new SpecialProcessCustomersData();
customers.show();
}


Also, note that show can call multiple methods on the Data object if
necessary, so it doesn't have to simply be pass-thru as in
these examples. In that case the concrete CustomerBase implementation
acts as a facade as well. Also, concrete CustomerBase
implementations would commonly have different, higher-level methods
than
the associated Data object.
Its useage might be even clearer if you look at a method that takes a
parameter of type, "CustomerBase". In that case the benefit
of both the abstraction and decoupling of implementation is more apparent:

public void ShowCustomerToUser(CustomerBase customer)
{
customer.show();
}

HTH

--
Dave Sexton

l'art pour decoupler une abstraction de son execution ;)
http://en.wikipedia.org/wiki/Bridge_pattern

Yes that is where I got it from :(

"decoupler une abstraction de son execution"
That is happening twice in my perception,
but that doesn't seem to be specific for
what the code is purporting to represent,
namely a bridge. I could image show, called
in main, and, in turn, calling ShowRecord, to
be the bridge. But what is so useful about
doing that? Obfuscation or 3-tier stuff?
 
D

Dave Sexton

Hi Adrian,

Glad I could help.
Unfortunately too often *only* know-how and know-when is explained.

I agree, but books and in-depth articles usually fill in the blanks nicely.

--
Dave Sexton

Adrian said:
Dave, I can see what you are getting at here. How the bridge pattern does a
better job
then polymorphism.

I have successfully implemented your suggestions to bear out the workings of
the example a bit better now.

Your remarks do a good job in explaining the know-why of the bridge pattern.

Unfortunately too often *only* know-how and know-when is explained.

Many thanks,
Adrian. (Nom de plume.)

Dave Sexton said:
Hi Adrian,

Exactly. By using an abstract class you can swap out the implementation
in the caller whenever you need to refactor your code and
it enables your code to be dynamic enough when you need to vary
implementations at runtime. The consumer of the class doesn't need
to be aware of the implemention, it just needs a reference to the
interface (abstract class in this case).
Be aware when using patterns that decouple implemention by using
polymorphism that if you see something like the following you
should probably invest your time in finding a more appropriate pattern to meet your needs:

public void ShowCustomerToUser(CustomerBase customer)
{
if (customer.GetType() == typeof(SpecialProcessCustomerData))
{
// we require a special process to occur first, in this case
customer.SpecialProcess();
}

// all customers may be "shown"
customer.show();
}

Hopefully you see the benefit of the bridge pattern and how it could be
used to alleviate any need for the explicit Type check
above. The idea is to "abstract" the "ShowCustomerToUser" method from
requiring a reference or any knowledge at all of the
implementation of the specified "customer" object.

public class SpecialProcessCustomerData : DataObject
{
public void show()
{
// TODO: special processing
// TODO: show something
}
}

--
Dave Sexton

Is using abstract and concrete classes (decoupling)
for hiding the concrete classes from users? If not,
why is it done?



Hi Adrian,

Maybe this link will clear it up more for you:

G.O.F. on Bridge:
http://www.dofactory.com/Patterns/PatternBridge.aspx


I believe you have partially identified the bridge. The part that you
didn't acknowledge is the two abstract classes and the
decoupling of the implementation.

The GOF example is much clearer, IMO. Look at the C# code sample.

To equate their sample to your sample:

[STAThread]
static void Main(string[] args)
{
Customers customers = new Customers("Chicago");
customers.Data = new CustomersData();
customers.show();

customers.Data = new PrimaryCustomersData();
customers.show();

customers.Data = new SpecialProcessCustomersData();
customers.show();
}


Also, note that show can call multiple methods on the Data object if
necessary, so it doesn't have to simply be pass-thru as in
these examples. In that case the concrete CustomerBase implementation
acts as a facade as well. Also, concrete CustomerBase
implementations would commonly have different, higher-level methods than
the associated Data object.

Its useage might be even clearer if you look at a method that takes a
parameter of type, "CustomerBase". In that case the benefit
of both the abstraction and decoupling of implementation is more apparent:

public void ShowCustomerToUser(CustomerBase customer)
{
customer.show();
}

HTH

--
Dave Sexton

l'art pour decoupler une abstraction de son execution ;)
http://en.wikipedia.org/wiki/Bridge_pattern

Yes that is where I got it from :(

"decoupler une abstraction de son execution"
That is happening twice in my perception,
but that doesn't seem to be specific for
what the code is purporting to represent,
namely a bridge. I could image show, called
in main, and, in turn, calling ShowRecord, to
be the bridge. But what is so useful about
doing that? Obfuscation or 3-tier stuff?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top