<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Lotushints &#187; bridge</title>
	<atom:link href="http://www.lotushints.com/tag/bridge/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.lotushints.com</link>
	<description>Lotus Notes tips &#38; tricks you always hoped you will not need</description>
	<lastBuildDate>Thu, 29 Dec 2011 09:47:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Design patterns &#8211; Part 11: Bridge pattern</title>
		<link>http://www.lotushints.com/2009/06/design-patterns-part-11-bridge-pattern/</link>
		<comments>http://www.lotushints.com/2009/06/design-patterns-part-11-bridge-pattern/#comments</comments>
		<pubDate>Mon, 01 Jun 2009 07:00:38 +0000</pubDate>
		<dc:creator>Vladimir Kocjancic</dc:creator>
				<category><![CDATA[Best practices]]></category>
		<category><![CDATA[Code optimization]]></category>
		<category><![CDATA[design patterns]]></category>
		<category><![CDATA[bridge]]></category>
		<category><![CDATA[custom classes]]></category>
		<category><![CDATA[Lotus Notes]]></category>
		<category><![CDATA[object-oriented]]></category>
		<category><![CDATA[Object-oriented development]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://www.lotushints.com/?p=361</guid>
		<description><![CDATA[In part 11 of Design pattern series we will go into creating and using the Bridge design pattern. It is moderately used and uses encapsulation, inheritance and aggregation to separate responsibilities into other classes. The Bridge pattern decouples an abstraction from its implementation so that the two can vary independently. Usage The pattern is most [...]]]></description>
			<content:encoded><![CDATA[<p>In part 11 of <a href="../category/design-patterns/">Design pattern series</a> we will go into creating and using the Bridge design pattern. It is moderately used and uses encapsulation, inheritance and aggregation to separate responsibilities into other classes.</p>
<blockquote><p><strong>The Bridge pattern</strong> decouples an abstraction from its implementation so that the two can vary independently.</p></blockquote>
<p><span id="more-361"></span></p>
<p><strong>Usage</strong></p>
<p>The pattern is most useful, when both classes (implementation and abstraction) are assigned to different task handling. In our example, we will look at how to separate data and actions to build a list of products and navigate it.</p>
<p><strong>Data representation class</strong></p>
<p>This is an abstract class with only navigational methods specified. Data representation class must implement navigational logic in its methods and thus assures that no other class will change or handle any properties without data representation class knowledge.</p>
<p>Also, for needs of our example, we will also define a type that will contain product id, name and price.</p>
<pre>Type TBridgeData
   strId As String
   strName As String
   dPrice As Double
End Type

Class CBridgeDataObject
   Sub NextRecord ()
   End Sub

   Sub PrevRecord ()
   End Sub

   Sub AddRecord (strId As String, strName As String,_
   dPrice As Double)
   End Sub

   Sub RemoveRecord (strId As String )
   End Sub

   Sub ShowRecord ()
   End Sub

   Function ShowAllRecords () As String
   End Function
End Class</pre>
<p><strong>Product data class</strong></p>
<p>Class itself inherits from Data representation abstract class. Also, it contains all navigational logic as well as data handling.</p>
<p>Beware that for this example, I did not actually load the data from the database. Instead I created five (5) products in the class construct. In real life, you should have read the data from your database!</p>
<pre>Class CBridgeProductData As CBridgeDataObject
   Private m_nCurrent As Integer
   Private m_AProducts () As TBridgeData

   Sub New ()
      m_ncurrent = 0

      Redim m_AProducts(4)

      m_AProducts(0).strId = "PR-0001"
      m_AProducts(0).strName = "Product 1"
      m_AProducts(0).dPrice = 100.00

      m_AProducts(1).strId = "PR-0002"
      m_AProducts(1).strName = "Product 2"
      m_AProducts(1).dPrice = 1000.00

      m_AProducts(2).strId = "PR-0003"
      m_AProducts(2).strName = "Product 3"
      m_AProducts(2).dPrice = 150.00

      m_AProducts(3).strId = "PR-0004"
      m_AProducts(3).strName = "Product 4"
      m_AProducts(3).dPrice = 400.00

      m_AProducts(4).strId = "PR-0005"
      m_AProducts(4).strName = "Product 5"
      m_AProducts(4).dPrice = 330.00
   End Sub

   Sub NextRecord ()
      If (m_nCurrent < Ubound (m_AProducts)) Then
         m_nCurrent = m_nCurrent + 1
      End If
   End Sub

   Sub PrevRecord ()
      If (m_nCurrent > 0) Then
         m_nCurrent = m_nCurrent - 1
      End If
   End Sub

   Sub AddRecord (strId As String, strName As String,_
   dPrice As Double)
      Dim n As Integer

      n = Ubound (m_AProducts) + 1
      Redim Preserve m_AProducts (n)

      m_AProducts(n).strId = strId
      m_AProducts(n).strName = strName
      m_AProducts(n).dPrice = dPrice
   End Sub

   Sub RemoveRecord (strId As String)
      Dim n As Integer
      Dim m As Integer
      Dim nCount As Integer
      Dim nIndex As Integer

      m = 0
      nIndex = -1
      nCount = Ubound (m_AProducts)
      For n = 0 To nCount
         If (m_AProducts (n).strId <> strId) Then
            m_AProducts (m).strId = m_AProducts (n).strId
            m_AProducts (m).strName = m_AProducts (n).strName
            m_AProducts (m).dPrice = m_AProducts (n).dPrice
            m = m + 1
         Else
            nIndex = n
         End If
      Next

      Redim Preserve m_AProducts (nCount - 1)
      If (m_nCurrent > n) Then Call Me.PrevRecord ()
   End Sub

   Sub ShowRecord ()
      Dim strDisplay As String

      strDisplay = m_AProducts (m_nCurrent).strId &#038; { } &#038;_
      m_AProducts (m_nCurrent).strName &#038; { €} &#038;_
      m_AProducts (m_nCurrent).dPrice

      Messagebox strDisplay
   End Sub

   Function ShowAllRecords() As String
      Dim n As Integer
      Dim strDisplay As String

      strDisplay = ""
      For n = 0 To Ubound (m_AProducts)
         strDisplay = strDisplay &#038; Chr(13) &#038;_
         m_AProducts (n).strId &#038; { } &#038;_
         m_AProducts (n).strName &#038; { €} &#038;_
         m_AProducts (n).dPrice
      Next

      ShowAllRecords = strDisplay
   End Function
End Class</pre>
<p><strong>Product base class</strong></p>
<p>Now, that we have our data classes created, we need to build an abstraction class that will call actual navigation and display the list contents or item if necessary. As we might have multiple classes that should have same functionality, it is a must to create a base class first. This class will encapsulate Data representation abstract class.</p>
<pre>Class CBridgeProductBase
   Private m_DataObj As CBridgeDataObject
   Private m_strGroup As String

   Public Property Get Data
      Set Data = m_DataObj
   End Property

   Public Property Set Data
      Set m_DataObj = Data
   End Property

   Sub New (strGroup As String)
      m_strGroup = strGroup
   End Sub

   Sub Next ()
      Call m_DataObj.NextRecord ()
   End Sub

   Sub Prev ()
      Call m_DataObj.PrevRecord ()
   End Sub

   Sub Add (strId As String, strName As String, dPrice As Double)
      Call m_DataObj.AddRecord (strId, strName, dPrice)
   End Sub

   Sub Remove (strId As String)
      Call m_DataObj.RemoveRecord (strId)
   End Sub

   Sub Show ()
      Call m_DataObj.ShowRecord()
   End Sub

   Sub ShowAll ()
      Messagebox "Product group: " &#038; m_strGroup &#038; Chr (13) &#038;_
      m_DataObj.ShowAllRecords()
   End Sub
End Class</pre>
<p><strong>Concrete product class</strong></p>
<p>Concrete product class in our case, will only be used to alter presentation when ShowAll method is called. This is not a must.</p>
<pre>Class CBridgeProducts As CBridgeProductBase
   Sub New (strGroup As String)
   End Sub

   Sub ShowAll ()
      Messagebox "Displaying all products"
      Call CBridgeProductBase..ShowAll ()
   End Sub
End Class</pre>
<p><strong>Implementation</strong></p>
<p>For test purposes, I have created an agent that will:</p>
<ul>
<li>create product list</li>
<li>navigate forward and backward</li>
<li>add an item to the list</li>
<li>remove an item from the list</li>
<li>display single product or all products at any time,</li>
</ul>
<pre>Sub Initialize
   Dim products As CBridgeProducts
   Dim data As CBridgeProductData

   Set products = New CBridgeProducts ("product group 1")
   Set products.Data = New CBridgeProductData ()

   Call products.Show ()
   Call products.Next ()
   Call products.Show ()
   Call products.Prev ()
   Call products.Show ()
   Call products.ShowAll ()

   Call products.Add ("PR-0010", "New product", 1475.00)
   Call products.ShowAll ()
   Call products.Remove ("PR-0004")
   Call products.ShowAll ()
End Sub</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.lotushints.com/2009/06/design-patterns-part-11-bridge-pattern/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

