You are not logged in.

#1 2008-12-01 23:57:13

RedShift
Member
From: Belgium
Registered: 2004-07-16
Posts: 230

Loose coupling and parents/children/related

Hello


I'm trying to achieve loose coupling between two objects that don't know about
each other, but in reality have a relation with each other.


I'm going to illustrate my attempt using a DNS example. Say that I have a
DnsZone and a DnsRecord class.


Ok, so why do I need the loose coupling? Because I'm writing an application that has
interchangeable backends. If a sysadmin isn't satisfied how this application
stores its information, he should be able to quickly change it the way he likes
it. A key element in making this possible is limiting the code that sysadmin
would have to write to construct his own implementation. Therefore, the interface
only specifies a very limited set of methods to implement, :

interface dnszone {
    public function getAll();
    public function save();
    public function add();
    public function del();
    // This is the DNS zone interface, get the name of the zone, example.com
    public function getName();
    // Get the type of the zone, for example "master"
    public function getType();
}


Another aspect of this application is seperation of powers. The application is
split up into three aspects:
* Lowlevel backends. One of these lowlevel backends like above. The only
control we have here is that these backends must implement a specific interface
and those methods must return a certain datatype.
* Business logic. This layer processes the information retrieved from the
lowlevel backends and definition files, to allow the information to be passed
to the presentation layer and the other way around, such as command a backend
to delete a specific entry.
* Presentation layer. This layer converts the supplied data by the business logic
into something humans can use.


Each class has a getAll() function they must implement.
* DnsZone will fetch all the DNS zones with information like zone name
(example.com) getName(), type (master||slave) getType(), etc...
* The DnsRecord class getAll() will get all the possible DNS records, like
record name (www.example.com) getName(), record type (A||MX||AAAA...) getType(),
result (1.2.3.4) getContent(), etc...


Now how do I achieve loose coupling in this model? Obviously a DnsZone has
DnsRecords, I'm searching for a proper way to allow the business logic layer
to know that a DnsZone has DnsRecords below it and a DnsRecord has a DnsZone
above it. Note that it doesn't always have to be a parent/child relation
(many-to-one), more like a possible many-to-many. It just is a parent/child
relation in this example.


There are a few options I've considered:

* Observer/parent/child style. The DnsRecord class is registered to the DnsZone
class as a child upon runtime. So when getAll() is done on DnsZone, it will
automatically call DnsRecord with an appropriate function to get all the records
belonging to that zone.

The drawback to this solution is that both classes become intertwined. The
DnsZone knows it has children and needs to reserve room for storing DnsRecords.
The DnsRecord in that regard needs to especially equipped to fetch DnsRecords
for a specific DnsZone. And the observer pattern itself is one-way communication
only, making it two-way is messy.


* DnsRecord extends the DnsZone object.

This is a probable solution, but it makes the DnsRecord object dependant of the
DnsZone object and causes a name conflict since both have to implement getAll().
Making the DnsRecord ignore getAll() and force to write for example getAllChilds()
then that would mean the DnsRecord actually is a child of the DnsZone, again
losing loose coupling.


Both of the above solutions are not acceptable since the sysadmin must write
functions to allow the relation to work. Since we consider the sysadmin a very
unreliable source, we must keep control over this ourselves.


Right now I'm kind of stuck in this brainteaser. Any tips/suggestions/coding
practices/related situations/etc... would be welcome.


:?

Offline

Board footer

Powered by FluxBB