Re: Design Pattern Question



Responding to Xllo...

One could use Adapter, Facade, or even Observer with some bending,
but Proxy is pretty much designed for restricted or selective access.

However, a priori I would regard this as a trick question because
there is a much easier answer than design patterns. If only one class
(Employee) is involved and the individual clients always access the
same properties, then all one really needs to do is define multiple
interfaces for Employee that only provide X, X+Y, or Z access. Then
one "hard-wires" the appropriate interface for each client. The
available interface then prevents the client from accessing
properties it shouldn't because they are not defined in that
interface.


I would like to explore this design further.
Assuming there is a heirarchy of classes.
Employee from which is derived ManagerEmployee,
HREmployee, HRManagerEmployee, etc.
So there are multiple issues here - the interaction between
different types of Employees. I would be ending up with
too many Proxy Classes if I were to define one for
each relationship - also if some requirements change
- i.e. suddenly it's decided that all Manager no longer has
access to an Employee's X property - only Senior Manager's
should be able to view it, it would involve a lot of code change.
What should be right design for this? Should I be having a
hierachy of employee classes & a lot of Proxy classes?
Are there better designs?

I agree with Daniel T. that generalization into multiple Employee types is not the way to go (unless the OOPL supports pure interface generalization). You have a basic class and just want to restrict access by certain clients to the properties of the class. So far there doesn't seem to be differences between members of that class that would justify thinking of them as different abstractions.

To use Proxy, the Employee class would be a subclass of something else and a sibling of the different interface proxies. Something like:

[EmployeeView]
// properties everyone can access
A
|
+---------------+--------------+------------+
| | | |
[Employee] [XProxy] [XYProxy] [ZProxy]
+ propX + propX + propX + propZ
+ propY + propY
+ propZ

In your case, though, I think things could be simpler to avoid the indirection of XProxy.propX invoking Employee.propX since the Proxy is just a pass-through. [It doesn't sound like your Proxies would have the sort of extra processing in the Proxy methods that the GoF examples have; you would just go directly to the Employee property. That processing is designed to resolve syntactic mismatches between the client expectations on the interface and that actually provided.]

In OOPLs like Java that support distinct interfaces, you just need to define the interfaces with the accessible properties, say iEmployeeX, iEmployeeXY, iEmployeeZ. Then you associate those interface with the Employee class

class Employee: iEmployeeX, iEmployeeXY, iEmployeeZ
{
.....
}

Then in a particular client you define the appropriate interface

Client::doIt(iEmployeeXY employee)
{
anA = employee.getPropertyA();
...
}

Here the passed "employee" is really just an Employee object and is accessed directly. The compiler won't let Client::DoIt access anything except properties identified in the iEmployeeXY interface, though. If the OOPL doesn't support pure interface definitions, you can always use the Facade pattern.

The GoF design patterns all address basically the same problem.

1 accesses 1
[A] ------------------ [B]

(The multiplicity can be, and often is, * on each end.) The problem
is that the specific services a B actually provides when accessed by
an A depend upon run-time context. Thus the properties can be
substituted from one collaboration to the next. In that situation
the dynamics of the relationship are too complex to express with a
simple association because of the substitution.

The GoF patterns address the dynamic nature of collaboration in
various ways depending on the specific problem context (i.e., one
particular pattern for each class of problems). In almost all GoF
patterns that dynamism is resolved with some combination of
delegation and polymorphic dispatch.

However, if the client always accesses exactly the same services in
every run-time context, then there is no dynamic substitution and the
GoF patterns tend to be overkill. In that case one looks for simpler
solutions like providing multiple interfaces for [B].


Can you elaborate?

On what? The whole concept? The last paragraph? IOW, what is it you are having a problem following?


*************
There is nothing wrong with me that could
not be cured by a capful of Drano.

H. S. Lahman
hsl@xxxxxxxxxxxxxxxxx
Pathfinder Solutions
http://www.pathfindermda.com
blog: http://pathfinderpeople.blogs.com/hslahman
"Model-Based Translation: The Next Step in Agile Development". Email
info@xxxxxxxxxxxxxxxxx for your copy.
Pathfinder is hiring: http://www.pathfindermda.com/about_us/careers_pos3.php.
(888)OOA-PATH



.



Relevant Pages

  • Re: treating an object as another type (not castable)
    ... proxy classes of web services cause a design problem. ... I guess the right design would be to an assembly containing the interface ... web service proxy. ...
    (microsoft.public.dotnet.framework.clr)
  • Re: When is a function not a function?
    ... a DOM element and Array or a value with falseness. ... betrays very poor code design. ... subject of the test is expected to be any of a javascript function ... There is nothing to say that an object implementing the Node interface should not be a function object. ...
    (comp.lang.javascript)
  • Re: Internet Access problems in Fedora Core 4
    ... using the raw ip was to factor out DNS from the troubleshooting. ... set right or your card's interface isn't setup right. ... nameserver <proxy if proxy does dns to you or isp's dns> ... PING 64.233.179.99 56bytes of data. ...
    (comp.os.linux.misc)
  • Re: XP Requirement Analysis?
    ... and use TDD to force the same design to emerge. ... > These principles, used with other XP situations like pair programming, ... OK, but you need to know what that interface is, so you must do some ... to buy a business value. ...
    (comp.object)
  • Re: New to JUnit... Eclipse Question
    ... You create the interface to get the caller to compile then you have to write the implementation to get it to pass. ... I've argued before with someone claimed that according to YAGNI you would never create an interface until you have two classes that would implement the interface. ... its not a license for being dumb or lazy and making stupid design choices - see the end of this email for an account of when it did happen on one of my previous teams. ... So there are many good reasons for using interfaces even if you don't have a bona fide "need" yet. ...
    (comp.lang.java.programmer)