What are acceptable ways to construct delegate classes? Is it acceptable to instantiate delegates with a reference to Self (resulting in tight, two-way coupling - possible in PerlLanguage), or is it preferred to only pass in the minimum amount of information to a Delegate? Does the answer depend on whether or not the ComposedClass? in question is an Aggregate or a Composition?
This seems at once useful and bad practice to me. I've been working in OOPerl for the past year so not sure if you can even do this, but here's the JavaLanguage equivalent -
class Account { private BillingInfo billingInfo; private ContactInfo contactInfo; private ProjectInfo projectInfo; public Account() { billingInfo = new BillingInfo(this); contactInfo = new ContactInfo(this); projectInfo = new ProjectInfo(this); } }I see the drawback behind this - we are exposing way too much information to each of the delegates, giving them access to everything else Account is compised of. So it is better to instantiate ProjectInfo (which let's say requires BillingInfo and ContactInfo), with just the information it needs? It tradeoff is that it seems a little less elegant.
-- SiqiChen?
It would be typical to instantiate delegates with a reference to this so that they can invoke methods in Account.
Thanks for that answer. This is something I've been struggling with because it seems to me that by passing in that reference, we are exposing too much information to the delegate. Each delegate has access to the entire public interface of the composed class (which in turn uses other delegates). Is it typical/recommended for delegates to be very tightly coupled to the composing class?
I have seen at least one description of DelegationPattern that specifically mentioned passing this to the delegate as a characteristic of the pattern. However, I would let the requirements dictate whether to pass this to delegates or not. If the delegates do not require reference to the delegating class, don't pass this, otherwise do so.
Even so, that's not delegation as I know it, which would be more like this:
interface AccountInterface { public void doSomething(); } class BillingInfo extends BillingThing implements AccountInterface { private Account account; BillingInfo(Account a) { account = a; } public void doSomething() { ...do BillingInfo thing... } } class ContactInfo extends ContactSplork implements AccountInterface { private Account account; ContactInfo(Account a) { account = a; } public void doSomething() { ...do ContactInfo thing... } } class ProjectInfo extends ProjectGurgle implements AccountInterface { private Account account; ProjectInfo(Account a) { account = a; } public void doSomething() { ...do ProjectInfo thing... } } class Account extends AccountWhuzzit implements AccountInterface { AccountInterface delegate; public Account() { delegate = new BillingInfo(this); } public void delegateToProjectInfo() { delegate = new ProjectInfo(this); } ...etc... public void doSomething() { delegate.doSomething(); } ...etc... }Is this what you meant? Given your choice of class names, I somewhat suspect it isn't.
-- DaveVoorhis
Well, not quite. As I understand it, from Wikipedia: the delegation pattern is a technique where an object outwardly expresses certain behaviour but in reality delegates responsibility for implementing that behavior to an associated object.
That is what I demonstrated above. I assumed that BillingInfo, ContactInfo, and ProjectInfo were intended to be delegates for Account, hence they all implement the same interface. In other words, Account outwardly expresses AccountInterface behaviour, but in reality delegates responsibility to either BillingInfo, ContactInfo, or ProjectInfo. -- DV
So what I had in mind is something more like this:
class Account extends AccountWhuzzit implements AccountInterface { private BillingInfo billingInfo; private ContactInfo contactInfo; private ProjectInfo projectInfo; public Account() { billingInfo = new BillingInfo (this); contactInfo = new ContactInfo (this); projectInfo = new ProjectInfo (this); } public Person getProjectLeader() { return projectInfo.getLeader(); } public Date getDateLastbilled() { return billingInfo.getDateLastBilled(); } public Person getContactPerson () { return contactInfo.getContactPerson(); } }Is this considered a DelegationPattern? I apologize if I'm getting my terms confused, as you can tell I'm pretty new at this stuff. -- SiqiChen?
In a strict sense, I believe that would not be considered a DelegationPattern. You're exposing some methods of Account's member elements in Account, but not actually implementing Account's functionality via an object that implements the same interface as Account. To be considered a DelegationPattern, Account and Account delegates should be essentially -- though, obviously, not necessarily practically -- interchangeable. -- DV