I am writing a program that manipulates encrypted virtual disks and encrypted flash drives (eg. importing disks into my application, mounting/unmounting, changing passwords etc.). I am still new to object-oriented design so I have run into the following problem.
I have identified three disk types:
- Disk stored in a file (virtual disk) on a hard-drive (fixed location)
- Disk stored in a file (virtual disk) on a removable device (eg. flash drive, absolute path can change)
- Encrypted flash drive (same as above but stored directly on the device so no filepath)
The operations i need to do over these disks are mounting, unmounting, checking for presence on the computer and changing password. The main problem i have is with the differences (and similarities) in storing their location (file on a hard-drive can do with only an absolute filepath; encrypted device can do with a device ID; file on a removable device needs both device ID and a relative path on the device).
I have came up with multiple solutions so far but none of which I liked. Is there a preferred way to do this? Or am I thinking about this the wrong way?
Edit: The solutions I came up with so far:
Solution 1:
- Creating an abstract base Disk class with abstract methods for the operations i need (and some data about mounting which is common to all disks).
- From the base class I derive a PhysicalDisk class and a VirtualDisk class. VirtualDisk stores its location as a fixed path (string) and PhysicalDisk stores its location in a RemovableDevice class (contains a device ID, status flags etc.). Both classes implement the operations from the base class with respect to how their location is stored.
- From the VirtualDisk class i then derive a RemovableVirtualDisk class, which adds a RemovableDevice class as a member and reimplements some of the parent methods to account for this change.
The problem is that the implemented methods in derived classes are very similar, varying mostly in respect to how the location of the disk is stored.
Solution 2:
- Creating one class for all disk types, eg. EncryptedDisk, which then stores the disk location using polymorphism, in an abstract DiskLocation class. From DiskLocation I derive a FileOnFixedDevice class (for virtual disks) and a RemovableDevice class (for encrypted drives). From that i further derive a FileOnRemovableDevice class (for virtual disks on removable drives).
- The classes implement a GetSystemLocation() method and a IsDeviceInSystem() method, which are then used uniformly in the EncryptedDisk class for all disk types.
The problem I had with this solution is that I perform checks for device availability even when it does not make sense (disks on hard-drives). Also I might need to have some specific information about the disk location in the future, not just polymorphic objects which could be anything.
Maybe the optimal design is somewhere in the middle? Or would some different approach solve my problems?