Design Pattern for Add-ons

Posts   
 
    
Bashar
User
Posts: 108
Joined: 11-Nov-2004
# Posted on: 05-Aug-2005 19:21:39   

Omar and I are creating a range of commercial business products for our company. Products like bookkeeping (accounting), inventory control, payroll and personnel, point-of-sale and so on. When studying the market, we discovered that some customers require Inventory Control only, while others wanted Inventory Control with bookkeeping, for example.

The problem is, the code base for the Inventory Control module and the Bookkeeping module should stay the same and they should, somehow, know whether the other module is installed and act accordingly.

For example, when posting a sales invoice, there are usually 3 steps to carry out if the bookkeeping module is NOT installed. BUT if the bookkeeping module is installed then there are 5 steps and not 3, and so forth and so on.

You can say that either module is an add-on to the other.

Now, my question is, 'is there a design pattern to working with add-ons that you know of that can help us in this situation?' confused

JimFoye avatar
JimFoye
User
Posts: 656
Joined: 22-Jun-2004
# Posted on: 05-Aug-2005 21:07:27   

I would say, IMHO, you want a factory to create whatever object does the invoicing. Then the factory checks to see what's installed and wraps one object in another (decorator pattern) or else sets the objects implementations of each object (strategy). Something like that?

[Edit]

In general, think delegation and composition. Factory assures the object gets created as it should.

pilotboba
User
Posts: 434
Joined: 05-Aug-2005
# Posted on: 05-Aug-2005 21:51:32   

Bashar wrote:

For example, when posting a sales invoice, there are usually 3 steps to carry out if the bookkeeping module is NOT installed. BUT if the bookkeeping module is installed then there are 5 steps and not 3, and so forth and so on.

Well,

The simplest way I would recommend is to have this info in a config file. Or, have a Modules table in your Db that a record is added for each module that is installed.

Do you use licenses files? You chould check to see if a licenses file exists for the module in question.

BOb

jeffreygg
User
Posts: 805
Joined: 26-Oct-2003
# Posted on: 07-Aug-2005 06:42:23   

Assume that each module is created as an independent assembly (there can be other ways to do this). A bootstrapper looks at a given directory, opens each assembly found there and looks for classes which implement a specific type. If it's found, the type registers itself (or gets registered) for whichever processes it needs to. Then, when, the process is executed, each type that is registered for the process gets the opportunity to execute. Sort of a combination of State and Strategy, I guess. simple_smile

So:


Public Interface IProcessRegistration

Property SupportedProcesses as ProcessCollection
Sub Register(registrar as ProcessRegistrar)

End Interface


Public Class BookkeepingModule
Implements IProcessRegistration
...
Public Sub Register(registrar as ProcessRegistrar) Implements IProcessRegistration.Register
For Each myProcess As Process In SupportedProcesses
registar.RegisterFor(myProcess)
Next
End Sub

End Class


Public Class PostInvoice

Public Property RegisteredParticipants as ParticpantsCollection
...
'The list includes the BookkeepingModuleClass
End Property

Public Function Execute as Boolean
For Each registrant as ProcessRegistrant In RegisteredParticipants
registrant.Execute()
Next
End Function

End Class

Jeff...