+ All Categories
Home > Documents > SYNERGY 2007

SYNERGY 2007

Date post: 10-Jan-2016
Category:
Upload: asis
View: 43 times
Download: 0 times
Share this document with a friend
Description:
SYNERGY 2007. Design Patterns and the Object Factory. Peter Bragg, Care Data Systems. Miami l Thursday, May 17th. The Company (Background). Care Data Systems Limited Based in Birmingham, UK Dataflex users since 1985 - PowerPoint PPT Presentation
36
SYNERGY 2007 Design Patterns and the Object Factory Miami Thursday, May 17th Peter Bragg, Care Data Systems
Transcript
Page 1: SYNERGY 2007

SYNERGY 2007

Design Patterns and the Object Factory

Miami Thursday, May 17th

Peter Bragg, Care Data Systems

Page 2: SYNERGY 2007

The Company (Background)

• Care Data Systems Limited

• Based in Birmingham, UK

• Dataflex users since 1985

• Employed that handsome, young fellow

Peter Bragg on September 18th 2001

• Senior Product Developer

Page 3: SYNERGY 2007

The Product (Background)

• Donorflex

• Comprehensive system designed to support the ‘Not for Profit’

sector

– donations management (financial control, gift aid, gifts in kind,

merchandise sales)

– fundraising and strategic development (campaign management

& control)

– relationship management (profiling, segmentation, targeting)

– operational support (acknowledgements, communications, action

plans)

– events management (charity events and third party fundraising

and sponsorship)

Page 4: SYNERGY 2007

Typical Clients (Background)

• Healthcare

• Education

• Arts

• Community Social Services

• Overseas Aid

• Disability Services

• Political Reform

• Religious Organisations

• Service Veterans

• Sport

Page 5: SYNERGY 2007
Page 6: SYNERGY 2007

Design Patterns and the Object Factory

Page 7: SYNERGY 2007

The Story Begins…

• January 17th 2007

Page 8: SYNERGY 2007

Design Patterns & the Object Factory

Page 9: SYNERGY 2007

Design Patterns & the Object Factory

• I answered the question so precisely

that no further comments were

required! (Erm…)

• No one is interested in Factories

• No one is using Factories

• Might make an interesting topic?

Page 10: SYNERGY 2007

Design Patterns & the Object Factory

• I am not a Design Pattern Expert

• ..at all!

• Knowledge limited to ‘what I do’

Page 11: SYNERGY 2007

Design Patterns & the Object Factory

Creational Design Patterns and the Object

Factory

…in donorflex

Page 12: SYNERGY 2007

Design Patterns & the Object Factory

• Our Design Need:

One Application (donorflex)

Different backends (Dataflex, MSSQL, ?)

Intelligent code optimisation/execution

Page 13: SYNERGY 2007

Design Patterns & the Object Factory

• Possible design solutions:

If, Else or Case Statements

Deferred creation of ‘Process’ Objects

• The need:

Call a process (e.g. a ‘search’) and

execute code appropriate for the backend.

Page 14: SYNERGY 2007

Design Patterns & the Object Factory

View Object (i.e. Enquiry)

Process Object (i.e. Enquiry Engine)

Procedure OnProcess

If (Backend=Dataflex) …

end

else if (Backend=MSSQL)…

end etc.

End_Procedure

Page 15: SYNERGY 2007

Design Patterns & the Object Factory

View Object (i.e. Enquiry)

Procedure DoRunEnquiry

Handle hoEnquiryEngine

If (Backend=Dataflex) Get Create U_ … to hoEnquiryEngine

else if (Backend=MSSQL) Get Create U_ …….

Send DoProcess of hoEnquiryEngine

send Destroy of hoEnquiryEngine

End_Procedure

Page 16: SYNERGY 2007

Design Patterns & the Object Factory

View Object (i.e. Enquiry)

Factory Object (oFactory)Responsible for creating appropriate Process Object

Procedure DoRunEnquiry

Send DoProcess of (Instance(oFactory(self)))

End_Procedure

Page 17: SYNERGY 2007

So how does it all hang together?

• Write different versions of a (business) process as classes:

cAbstractPowerSearch (defines interface)

cPowerSearch_df is a cAbstractPowerSearch

cPowerSearch_mssql is a cAbstractPowerSearch

• Classes are then registered with a “Factory”:

Page 18: SYNERGY 2007

Design Patterns & the Object Factory

Class cPowerSearchEnq_Factory is a cFactory

Procedure Construct_Object Forward Send Construct_Object

Send RegisterType Factory_Type_Dataflex U_cPowerSearch_DF Send RegisterType Factory_Type_MSSQL U_cPowerSearch_MSSQL End_Procedure

End_Class

Page 19: SYNERGY 2007

So how does it all hang together?

• An instance of the factory is then added to a view

Object oPowerSearchEnq Is A cPowerSearchEnq_FactoryEnd_Object

• A call is then made to an ‘Instance’ of this Factory

So instead of:

Send DoProcess of oPowerSearchEnq

We would code:

Send DoProcess of (Instance(oPowerSearchEnq(self)))

• A ‘singleton’ Factory Controller instructs the Factory which

version of the process to create

Page 20: SYNERGY 2007

Factory Controller ClassEnum_List Define Factory_Type_Dataflex Define Factory_Type_MSSQL Define Factory_Type_Pervasive Define Factory_Type_MySQL Define All_Factory_Types //need to be last – gives number of defined typesEnd_Enum_List

Class cFactoryController is a cObject Procedure Construct_Object String sEngine Forward Send Construct_Object Property Integer piCurrentType Factory_Type_Dataflex // Default type. // Check the application object: Get psFactoryEngine of ghoApplication to sEngine //set during OnCreate of Application object Case Begin Case (sEngine = "mssql") Set piCurrentType to Factory_Type_MSSQL Case Break Case End End_Procedure // Construct_Object

Function CurrentType Returns Integer Function_Return (piCurrentType(Self)) End_FunctionEnd_Class

Page 21: SYNERGY 2007

Factory Controller Object

Global_Variable Handle ghFactoryControllerGet Create of Desktop U_cFactoryController to ghFactoryController

Page 22: SYNERGY 2007

The Factory ClassClass cFactory is a cObject Procedure Construct_Object integer[] iTypeMappings

Forward Send Construct_Object

// Holds the type of the current factory object: Property Integer piInstanceType (CurrentType(ghFactoryController)) // Holds the object instance that this factory object represents: Property Handle phInstance 0 // Initially zero. // Array that holds class identifiers to be constructed dependant on the required type: Property Integer[] piTypeMappings

//initialise piTypeMappings Array to avoid index out of range errors move 0 to iTypeMappings[All_Factory_Types] Set piTypeMappings to iTypeMappings End_Procedure // Construct_Object // Provides a means by which to 'register' what class should be used against a particular type of connection: Procedure RegisterType Integer iType Integer iClass integer[] iTypeMappings Get piTypeMappings to iTypeMappings move iClass to iTypeMappings[iType] Set piTypeMappings to iTypeMappings

End_Procedure

Page 23: SYNERGY 2007

The Factory Class… // Returns the class associated by a previous call to RegisterType: Function TypeClass Integer iType Returns Integer Integer iClass integer[] iTypeMappings Get piTypeMappings to iTypeMappings move iTypeMappings[iType] to iClass // if we don't find a registered class of the type we are looking for, look for and return the native dataflex // factory type.. if (iClass = 0) move iTypeMappings[Factory_Type_Dataflex] to iClass // Support drop through the default // type. // if we still have no registered class, we must give an error if (iClass = 0) Error 4113 ("Programmatic Error - No registered type for factory "+name(self)) Function_Return iClass End_Function // Returns the current 'type' associated with this factory: Function InstanceType Returns Integer Function_Return (piInstanceType(Self)) End_Function // Allows a new type to be set against this object: Procedure Set InstanceType Integer iType Set piInstanceType to iType End_Procedure

Page 24: SYNERGY 2007

The Factory Class… // Returns or creates the correct instance of a type for this factory: Function Instance Returns Handle Handle hObj Integer iType iNewType Get phInstance to hObj Get InstanceType to iType Get CurrentType of ghFactoryController to iNewType // If the type doesn't match what we are currently using then destroy the object and create a new one: If ((iType <> iNewType) And (hObj <> 0)) Begin Send Destroy of hObj Move 0 to hObj End

If (Not(hObj)) Begin Get Create (TypeClass(Self, iNewType)) to hObj Set phInstance to hObj Set InstanceType to iNewType End Function_Return hObj End_Function // Boolean function that tells the caller if the factory instance has been created yet: Function IsCreated Returns Boolean Function_Return (phInstance(self) <> 0) End_Function End_Class

Page 25: SYNERGY 2007

A Simple Example

• User logs in and we look to see if they have any communications to make.• Code we execute will depend on the backend• So we will use a factory for this…

Page 26: SYNERGY 2007

A Simple Example

Use cFactory.pkg

Define the interface:

class cAbstractLoginPrompts is a cObject Function DoFindLoginPrompts string sUser date dDate integer iDays returns integer[] end_function end_class

Or sometimes..

class cAbstractLoginPrompts is a cObject Function DoFindLoginPrompts string sUser date dDate integer iDays returns integer[] Error DFErr_Program “Method not defined for concrete class” end_function end_class

Page 27: SYNERGY 2007

A Simple Example

Write the classes:

class cLoginPrompts_df is a cAbstractLoginPrompts Function DoFindLoginPrompts string sUser date dDate integer iDays returns integer[] integer[3] iRetVal //outstanding/today/future integer iOverdue iToday iFuture open doncomms For_All DONCOMMS BY Index.3 Constrain Doncomms.On_behalf_of EQ sUser Constrain Doncomms.Login_prompt EQ "Y" DO if (doncomms.date < dDate) increment iOverdue else if (doncomms.date = dDate) increment iToday else if (doncomms.date <= (dDate+iDays-1)) increment iFuture End_For_All move iOverdue to iRetVal[0] move iToday to iRetVal[1] move iFuture to iRetVal[2] function_return iRetVal end_function end_class

Page 28: SYNERGY 2007

A Simple Example class cLoginPrompts_sql is a cAbstractLoginPrompts Function DoFindLoginPrompts string sUser date dDate integer iDays returns integer[] integer[3] iRetVal //outstanding/today/future integer iFetchResult iCount iData handle hSQLInstance hConn hSQL string sSQL sDate sDateFuture sBase boolean bNoMoreResultSets move (Instance(ghSQLConnectionFactory)) to hSQLInstance

move ("Select count(*) from doncomms where doncomms.On_behalf_of = '"+sUser+"' and doncomms.Entity = 'R' and doncomms.Login_prompt = 'Y' and ") to sBase

Get DateToSQL of hSQLInstance dDate to sDate move (sSQL+sBase+"doncomms.Date < '"+sDate+"';") to sSQL move (sSQL+sBase+"doncomms.Date = '"+sDate+"';") to sSQL Get DateToSQL of hSQLInstance (dDate+1) to sDate Get DateToSQL of hSQLInstance (dDate+iDays-1) to sDateFuture move (sSQL+sBase+"doncomms.date between '"+sDate+"' and '"+sDateFuture+"';") to sSQL // Open Connection Get Connection of hSQLInstance to hConn Get SQLOpen of hConn to hSQL // Send the Statement .. Send SQLExecDirect of hSQL sSQL move False to bNoMoreResultSets

Page 29: SYNERGY 2007

A Simple Example Repeat Get SQLFetch Of hSQL To iFetchResult If (iFetchResult <> 0) begin move (trim(SQLColumnValue(hSQL,1))) to iData increment iCount move iData to iRetVal[iCount-1] end Get SQLNextResultSet of hSQL to iFetchResult if (not(iFetchResult)) move True to bNoMoreResultSets Until (bNoMoreResultSets) // Release the Statement: Send SQLClose of hSQL function_return iRetVal end_function end_class

Page 30: SYNERGY 2007

A Simple Example

Write a factory class and register both classes:

class cLoginPrompts_Factory is a cFactory

Procedure Construct_Object Forward Send Construct_Object

// Register the default class that will be used as a drop through if other types aren't // registered: Send RegisterType Factory_Type_Dataflex U_cLoginPrompts_df Send RegisterType Factory_Type_MSSQL U_cLoginPrompts_sql End_Procedure end_Class

Create an Object instance of the Factory

Object oLoginPromptsFactory is a cLoginPrompts_FactoryEnd_object

Page 31: SYNERGY 2007

A Simple Example

Then call the function and let the factory do the rest

Integer[] iRetVal

Get DoFindLoginPrompts of (instance(oLoginPromptsFactory(Self))) sUser dDate iDays to iRetVal

Under the hood:

• The function “Instance” asks “have I already created an object for you?”• If so, it simply returns a handle to the object it created earlier• If not:

It looks to see what the “Factory Controller” says it should be creating It creates an object of the required class It sets a property with the handle of the object It returns a handle to the object “DoFindLoginPrompts” is then executed

Page 32: SYNERGY 2007

Another Example:

Page 33: SYNERGY 2007

How it works…

Use dnTreeView.pkgUse cProfileFactory.pkg

class cProfileTree is a dnTreeView

Import_Class_Protocol Server_Mixin Procedure Construct_Object forward send Construct_Object Property Integer piPrivate.CurrentProfile 0 Property Integer piPrivate.HelpArray_ID 0 Property Handle phProfileTreeFactory (Create(self,U_cProfileTree_Factory)) Send Define_Server // Set tree properties: Set TreeLinesState to False Set TreeRootLinesState to False Object PopupMenu is a cProfilePopUpMenu Delegate Set PopupMenu_ID to Self End_Object end_procedure

Page 34: SYNERGY 2007

How it works…

Page 35: SYNERGY 2007

Design Patterns & the Object Factory

• Using this ‘Factory’ approach as a model:

“The need to know” - objects only get involved

with what they need to. Views simply make a call

to a common interface and don’t care about what

lies behind this.

Scalability – new classes can be written and

registered with a Factory very easily.

Easy to code and implement new factory

instances.

Page 36: SYNERGY 2007

SYNERGY 2007

Thank You

Miami Thursday, May 17th


Recommended