The first task is to understand the problem clearly. Let's see what we can dig out of your description:

  1. You have widgets of various types.
  2. Each type of widget has a set of properties.
  3. Each type of property has an associated set of events that you want to trigger when a widget having a property of that type is inserted.
  4. There are many types of events.

Most of that is straightforward. The only tricky part is understanding the relationships among property types and the events you want to trigger. Ignoring design and implementation issues for now, let's just create a written specification to capture these relationships. For example, we might have the following:

PropertyA triggers Event1(a), Event3(b) PropertyB # triggers no events PropertyC triggers Event3(c) ...
The first line says, "Properties of type A trigger an event of type 1 having parameters a and also trigger an event of type 3 having parameters b." Alternatively, we could specify these relationships in a table, which might make things clearer, and/or easier to maintain:
Property Event 1 2 3 4 ... ======== =========== A a b B C c ...

Because these relationships are the crux of your maintenance concerns, we ought to make them easy for humans to specify and change. I would therefore not represent them as code. Rather, I would try to use a representation as close to the specifications above as possible, optimizing for humans instead of the computer. For example, we could use a configuration file similar to our first specification or a database table modeled on the second.

In either case, our implementation would read the specifications upon initialization and then wire up the relationships accordingly via code generation or other means. The idea is to make the computer do the work, not humans.

For example, our wiring might be as simple as converting the specifications into a lookup table that maps property names (class name) to event handlers:

my $property_type_events = { Property::A => [ handler { Event::E1->new(@_) } 'a' , handler { Event::E3->new(@_) } 'b' ] Property::B => [ ], Property::C => [ handler { Event::E3->new(@_) } 'c' ], ... };
Here, handler is a helper function that takes a block of code that builds an event object of a particular type using the given run-time parameters (represented by placeholders like 'a' and 'b') and returns a function that when called creates and triggers the event:
sub handler(&@) { my ($event_ctor, @args) = @_; return sub { my $event = $event_ctor->(@args); return $event->trigger(@_); }; }

Now, just make sure that all of your Widget objects have a get_properties method that returns a list of the properties they have, and it's easy to handle the event triggering for an arbitrary widget:

sub handle_widget_insertion_events($) { my ($widget) = @_; for my $property ($widget->get_properties) { my $handlers = $property_type_events{ ref($property) }; next unless $handlers; for my $handler (@$handlers) { my $rc = $handler->( "pass trigger args here" ); # do something with result code $rc } } }
That's the approach that I would take: Make the tricky relationships easy to maintain by tailoring their representation for the purpose. The implementation can then be built automatically from that representation.

I would repeat the approach for the other parts of the problem where it makes sense. For example, if the relationships among widget types and their properties are complicated, I would create an external specification for them, too, and build code from that.

Hope this helps.

Cheers,
Tom


In reply to Re: OT: Design question by tmoertel
in thread OT: Design question by dragonchild

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.