⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tiofp documentation - building an abstract bom with the composite pattern.htm

📁 tiOPF 面向对象的数据库持久层持久层开发的框架
💻 HTM
📖 第 1 页 / 共 5 页
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0082)http://www.techinsite.com.au/tiOPF/Doc/4_BuildingAnAbstractBOMWithTheComposite.htm -->
<HTML><HEAD><TITLE>tiOFP Documentation - Building an abstract BOM with the composite pattern</TITLE>
<META http-equiv=Content-Type content="text/html; charset=gb2312"><!-- InstanceBegin template="/Templates/TechInsite_Template.dwt" codeOutsideHTMLIsLocked="false" --><!-- InstanceBeginEditable name="doctitle" --><!-- InstanceEndEditable --><!-- InstanceBeginEditable name="head" --><!-- InstanceEndEditable --><LINK 
href="tiOFP Documentation - Building an abstract BOM with the composite pattern_files/TechInsite.css" 
type=text/css rel=stylesheet>
<META content="MSHTML 6.00.3790.1830" name=GENERATOR></HEAD>
<BODY>
<SCRIPT type=text/javascript>function Go(){return}</SCRIPT>

<SCRIPT 
src="tiOFP Documentation - Building an abstract BOM with the composite pattern_files/MainMenu_TechInsite.js" 
type=text/javascript></SCRIPT>

<SCRIPT 
src="tiOFP Documentation - Building an abstract BOM with the composite pattern_files/HVMenu.js" 
type=text/javascript></SCRIPT>
<NOSCRIPT>Your browser does not support script</NOSCRIPT> 
<DIV id=Container><IMG height=75 alt="" 
src="tiOFP Documentation - Building an abstract BOM with the composite pattern_files/Banner01.jpg" 
width=600 border=0> 
<TABLE cellPadding=5 valign="middle">
  <TBODY>
  <TR>
    <TD>
      <DIV id=pageheader1>TechInsite</DIV></TD>
    <TD>
      <DIV id=pageheader2>Home of the TechInsite Object Persistence 
      Framework<BR>Melbourne, Australia</DIV></TD></TR></TBODY></TABLE>
<HR>

<TABLE>
  <TBODY>
  <TR>
    <TD>
      <DIV id=HMenu style="POSITION: relative"></DIV></TD></TR></TBODY></TABLE><BR>
<HR>
<!-- InstanceBeginEditable name="Page title" -->
<H1>4. Building an Abstract BOM with the Composite Pattern </H1><!-- InstanceEndEditable --><!-- InstanceBeginEditable name="Page body" -->
<H1 class=Normal>The aims of this section </H1>
<P>In the previous two chapters we investigated how the Visitor and Template 
Method patterns can be used together to manage objects that are saved to either 
a custom text file, or a relational database. In these chapters, we started to 
develop an abstract collection class, and abstract business object class and we 
will extend these classes, adding more of the functionality that will be 
required in a complex business system.</P>
<H2>Prerequisites</H2>
<P>This chapter builds on the concepts introduced in chapter #2 ‘The Visitor 
Framework’ so it will be a good idea to read this chapter first.</P>
<P>The business problem we will work with as an example</P>
<P>The previous business object model</P>
<P>We will continue to develop the contact management application, and will 
extend the business object model to represent the data more realistically. In 
the previous chapter, we created a TPerson class and its corresponding 
collection class TPeople. This class diagram looked like this:</P>
<P><IMG height=89 
src="tiOFP Documentation - Building an abstract BOM with the composite pattern_files/4_BuildingAnAbstractBOMWithTheComposite_clip_image001.gif" 
width=275> </P>
<P>Rework the address book BOM to better represent the business domain</P>
<P>We shall do several things to improve this business object model. Firstly, 
the properties that a TPerson can have shall be replaced by the more usual 
LastName, FirstName, Title and Initials. Secondly, instead of each person only 
being able to have one EMail address, we shall allow them to have a list of what 
we will call E-Addresses. An E-Address shall be a one-line address that can 
contain a phone number, fax number, email address or web URL. (The example 
application ‘DemoTIPerFramework’ extends this model further so people can have 
street or post office box addresses too.) The UML of the extended TPerson family 
of classes looks like this:</P>
<P><IMG height=280 
src="tiOFP Documentation - Building an abstract BOM with the composite pattern_files/4_BuildingAnAbstractBOMWithTheComposite_clip_image002.jpg" 
width=427> </P>
<P>From this diagram we can see four classes:</P>
<TABLE cellSpacing=0 cellPadding=0>
  <TBODY>
  <TR class=Normal>
    <TD vAlign=top width=111>
      <P><STRONG>Class </STRONG></P></TD>
    <TD vAlign=top width=479>
      <P><STRONG>Description </STRONG></P></TD></TR>
  <TR class=Normal>
    <TD vAlign=top width=111>
      <P>TPeople </P></TD>
    <TD vAlign=top width=479>
      <P>A list of TPerson(s). Descends from TPerVisList and implements list 
      management methods like GetItems( I ) : TPerson and Add( pData : TPerson ) 
      </P></TD></TR>
  <TR class=Normal>
    <TD vAlign=top width=111>
      <P>TPerson </P></TD>
    <TD vAlign=top width=479>
      <P>A person object that descends from TPerObjAbs. Owned by TPeople. Has 
      published properties for LastName, FirstName, Title and Initials. Has a 
      property EAdrsList that is of type TEAdrsList to hold a list of 
      E-Addresses. </P></TD></TR>
  <TR class=Normal>
    <TD vAlign=top width=111>
      <P>TAdrsList </P></TD>
    <TD vAlign=top width=479>
      <P>A container for TEAdrs objects, descends from TPerVisList </P></TD></TR>
  <TR class=Normal>
    <TD vAlign=top width=111>
      <P>TEAdrs </P></TD>
    <TD vAlign=top width=479>
      <P>An electronic address object that belong to the TPerson. Descends from 
      TPerObjAbs and has properties Address type and address text. 
  </P></TD></TR></TBODY></TABLE>
<P>We shall concentrate on implementing a useful abstract business object and 
business object list first, then implement concrete classes towards the end of 
this chapter. After we have implemented the class structure, we shall write some 
helper functions that use the features in the abstract business objects to 
output the class hierarchy as text for debugging, or to search a hierarchy for 
an object with a given set of properties..</P>
<H2>The Composite pattern – what GoF say</H2>
<P>The intent of the Composite, as quoted from ‘Design Patterns’: Compose 
objects into tree structures to represent whole-part hierarchies. Composite lets 
clients treat individual objects and compositions of objects uniformly.</P>
<H2>Implementing the abstract business object model</H2>
<P>A type safe relationship between the collection and business objects</P>
<P>The first thing we shall do is to establish the relationship between the 
abstract collection class and the abstract business object class. The Composite 
pattern has introduced us to the idea of treating list objects and regular 
business objects as the same type of class, so we shall continue with the idea 
of the collection class descending from the business object class. The UML 
representing the relationship, which we setup in a pervious chapter looks like 
this:</P>
<P><IMG height=290 
src="tiOFP Documentation - Building an abstract BOM with the composite pattern_files/4_BuildingAnAbstractBOMWithTheComposite_clip_image001_0000.gif" 
width=346> </P>
<P>The Visitor – Visited relationship was discussed in chapter #2. Our abstract 
persistent objects will descend from TVisited because we want to be able to pass 
visitors over collections of objects with as little work as possible from the 
programmer. We will be focusing on the relationship between TPerObjAbs and 
TPerObjList next, but first we will add the list like behavior to 
TPerObjList.</P>
<H2>Adding list behavior to TPerObjAbs</H2>
<P>The first question is what behavior should we be adding to TPerObjAbs to turn 
it into a useful collection class? Delphi’s TList help text provides a good 
starting point as it details the properties and methods of the TList class. 
These are shown below:</P>
<TABLE cellSpacing=0 cellPadding=0>
  <TBODY>
  <TR>
    <TD vAlign=top width=295>
      <P align=center><STRONG>Properties </STRONG></P></TD>
    <TD vAlign=top width=295>
      <P align=center><STRONG>Methods </STRONG></P></TD></TR>
  <TR>
    <TD vAlign=top width=295>
      <P align=center> </P>
      <P align=center><IMG height=145 
      src="tiOFP Documentation - Building an abstract BOM with the composite pattern_files/4_BuildingAnAbstractBOMWithTheComposite_clip_image002_0000.jpg" 
      width=197></P></TD>
    <TD vAlign=top width=295>
      <P align=center> </P>
      <P align=center><IMG height=320 
      src="tiOFP Documentation - Building an abstract BOM with the composite pattern_files/4_BuildingAnAbstractBOMWithTheComposite_clip_image004.jpg" 
      width=165></P></TD></TR></TBODY></TABLE>
<P>Of these, we will start by adding the properties Items and Count, and the 
methods Add, Clear, Delete, First, IndexOf, Insert, Last and Remove. To make it 
as easy as possible for developers who are new to the framework, we will give 
the methods the same signature (or parameters and return type) as in Delphi’s 
TList class, with one change: Where the TList takes a TObject or Pointer as a 
parameter, we will substitute a TPerObjAbs. Here is the class diagram:</P>
<P><IMG height=224 
src="tiOFP Documentation - Building an abstract BOM with the composite pattern_files/4_BuildingAnAbstractBOMWithTheComposite_clip_image001_0001.gif" 
width=368> </P>
<P>The interface of TPerObjList is shown below:</P><PRE>TPerObjList = class( TPerObjAbs )
private
  FList : TObjectList ;
  function GetList: TList;
protected
  function GetItems(pIndex: integer): TPerObjAbs; virtual ;
  procedure SetItems(pIndex: integer; const Value: TPerObjAbs); virtual ;
  function GetCount: integer; virtual;
public
  // Constructor &amp; Destructor
  constructor Create ; override ;
  destructor Destroy ; override ;
  // Public properties
  property List : TList read GetList ;
  property Items[ pIndex : integer ] : TPerObjAbs read GetItems write SetItems ;
  property Count : integer read GetCount ;
  // Public methods
  procedure Add( pData : TObject ) ; virtual ;
  procedure Clear ; virtual ;
  procedure Delete( pIndex : integer ) ; virtual ;
  function First : TPerObjAbs ; virtual ;
  function IndexOf( pData : TPerObjAbs ) : integer ; virtual ;
  procedure Insert( pIndex : integer ; pData : TPerObjAbs ) ; virtual ;
  function Last : TPerObjAbs ; virtual ;
  procedure Remove( pData : TPerObjAbs ) ; virtual ;
  // The Iterate method is still overridden here as we are using the code
  // base we developed in the earlier chapter on the Visitor
  procedure Iterate( pVisitor : TVisitor ) ; override ;
end ;</PRE>
<P>The implementation of TPerObjList is rather dull as each method simply 
delegates the work to the owned TObjectList (with some type casting as 
necessary) like this:</P><PRE>function TPerObjList.Last: TPerObjAbs;
begin
  result := TPerObjAbs( FList.Last ) ;
end;</PRE>
<P>We shall add one extra property to TPerObjAbs called &amp;quo;owner&amp;quo;. 
Owner will behave in much the same way that Delphi&amp;quo;s TComponent.Owner 
property behaves. When we add an object to a TPerObjList, we shall take the 
opportunity to set its owner property as shown below:</P><PRE>procedure TPerObjList.Add(pData: TObject);
begin
  FList.Add( pData ) ;
  pData.Owner := Self ;
end;</PRE>
<P>The details of the relationship between TPerObjAbs and TPerObjList are shown 
in the UML below.</P>
<P><IMG height=293 
src="tiOFP Documentation - Building an abstract BOM with the composite pattern_files/4_BuildingAnAbstractBOMWithTheComposite_clip_image001_0002.gif" 
width=421> </P>
<P>This diagram tells us 3 things.</P>
<OL>
  <LI>TPerObjList inherits from TPerObjAbs. This means we can treat both classes 
  in the same way. This has significant benefits when we start building concrete 
  business classes. 
  <P></P>
  <LI>TPerObjList maintains an internal list of TPerObjAbs. This list can 
  contain 0 or many instances of TPerObjAbs. The owned instances of TPerObjAbs 
  are indexed by the Items property. 
  <LI>TPerObjAbs has a property Owner of type TPerObjAbs. If a TPerObjList owns 
  an instance of TPerObjAbs, the owner property of the TPerObjAbs will have been 
  set to the instance of TPerObjList in its Add method. If a TPerObjAbs owns 
  another TPerObjAbs, the programmer will have to set the Owner property 
  manually in code. </LI></OL>
<P>The need to make the iterate method generic</P>
<P>Now that we have coded a firm relationship between TPerObjAbs and 
TPerObjList, we can look at how to make the iterate method more generic. The 
implementation of iterate that we developed in chapter #2 looks like this:</P><PRE>procedure TPerObjList.Iterate(pVisitor: TVisitor);
var
  i : integer ;
begin
  inherited Iterate( pVisitor ) ;
  for i := 0 to FList.Count - 1 do

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -