Using inheritance for the models, with an OS-neutral BaseModel class and a Mac OS specific MacOsModel subclass seemed like it made sense at the time, but now I realize that to see the methods available to the model you have to consult both classes. That approach hides information, requiring a lot of effort to find the complete set of methods.
One solution would be to specify the base class methods absent from the subclass in that subclass, and explicitly delegate to the superclass (probably using Forwardable).
Another solution would be to create a module for the OS-neutral functionality, and include and use it. This would discard the use of inheritance.
However, a big challenge is that calls between the base class and its subclasses are bidirectional. For example, run_os_command in the base class is called by subclasses to do the low level OS-neutral work of calling an OS command, and remove_preferred_networks calls the subclasses' preferred_networks method to see if the network to delete is present in the list.
So perhaps the solution is to create 3 classes or modules containing: a) the OS-specific methods, b) the shared methods called by the OS-specific methods, and c) the shared methods that call OS-specific methods. But what would that look like, and would it really be less complex than inheritance?
One suggestion I have received is to create OS-specific drivers. The problem with this is that in this case the driver would be unable to call methods of the object that created it, unless that were explicitly implemented by passing a reference to itself; and to me, bidirectional dependency is much more problematic between 2 "unrelated" class instances than with super/sub class instances. So again we're looking at 3 code modules instead of 2.
I do think that seeing all available methods in one place is extremely important and might justify some ugliness elsewhere.
Using inheritance for the models, with an OS-neutral BaseModel class and a Mac OS specific MacOsModel subclass seemed like it made sense at the time, but now I realize that to see the methods available to the model you have to consult both classes. That approach hides information, requiring a lot of effort to find the complete set of methods.
One solution would be to specify the base class methods absent from the subclass in that subclass, and explicitly delegate to the superclass (probably using
Forwardable
).Another solution would be to create a module for the OS-neutral functionality, and include and use it. This would discard the use of inheritance.
However, a big challenge is that calls between the base class and its subclasses are bidirectional. For example,
run_os_command
in the base class is called by subclasses to do the low level OS-neutral work of calling an OS command, andremove_preferred_networks
calls the subclasses'preferred_networks
method to see if the network to delete is present in the list.So perhaps the solution is to create 3 classes or modules containing: a) the OS-specific methods, b) the shared methods called by the OS-specific methods, and c) the shared methods that call OS-specific methods. But what would that look like, and would it really be less complex than inheritance?
One suggestion I have received is to create OS-specific drivers. The problem with this is that in this case the driver would be unable to call methods of the object that created it, unless that were explicitly implemented by passing a reference to itself; and to me, bidirectional dependency is much more problematic between 2 "unrelated" class instances than with super/sub class instances. So again we're looking at 3 code modules instead of 2.
I do think that seeing all available methods in one place is extremely important and might justify some ugliness elsewhere.