My original thoughs were:
1.) from logical point of view to have one common parent (ancestor)
class, which will contain all common attributes (such as start and
stop methods definition, alert statements, timeout, etc.) and
specialized child (descendant) classes which will inherite common
properties and extend it by its own specialized attributes (for tests,
etc.) All common options (such as start and stop program, etc.) will
be possible to use in all services types and they will have
"wellknown" behavior.
2.) from physical point of view it is implemented as only one class
instance (Service_T), which is logical descendant of all above
mentioned classes, some (ugly) ascii art:
Common_T
/ | | \
/ | | \
/ | | \
File_T Device_T Process_T Directory_T
\ | | /
\ | | /
\ | | /
Service_T
Predecessor classes are not realy declared (they are "as virtual as
possible" => they don't exist :) Its instances are chained in simple
list. Specialized elements which are not utilized in particular
monitoring service type are ignored in appropriate particular
Service_T instance.