Part of the ObjectBasedProgramming pattern language.
Should the SetState?() method really have been included at the top of the class hierarchy in the Condition Class?
I think we should come up with a better example. Although the example is correct and valid - without the context - it is very hard to appreciate our particular application. The SetState?() method is only available in the SimpleCondition? and LeafAlarm? class. -- StephenCheng
The attributes called nParentAlarmHandle, nNextSiblingAlarmHandle and nFirstChildAlarmHandle seem to be present so to implement a 'linked list' or similar .... is this correct? If so should the fact that there is a 'list of Alarms' really be abstracted out of the Class definition. What about a declaring a node in your linked list of Alarms as:
Not a linked list - a tree structure instead. We definitely need another example, I will try knocking out a more universal example next week. -- StephenCheng
typedef struct AlarmNode? { Alarm *thisAlarm, Alarm *nextAlarm, Alarm *previousAlarm } AlarmNode?;Another option is to actually 'have' the Alarm object be WITHIN the AlarmNode? object, rather than have a pointer to an Alarm in the AlarmNode? struct, remove the * operator so that it IS an Alarm.
If I am completely off what was intended .. just delete my paragraphs above!
-- ScottWalsh
There had been voices raised elsewhere as to why the PolymorphicFunction pattern requires the instance data to be passed as an opaque reference (void*), rather than an exposed data type (e.g. tsTypeStructure*). The reason is to provide total abstraction of the design of the instance data. Collaborating classes have no knowledge of the structure of the instance data of the said class. As a result, the design of the instance data can be completely overhauled without affecting the collaborating classes.
One subtle point easy missed is: The instance data may not be a single data structure. The instance data can be made up of multiple data structures. It can even be a file handle or a TCP/IP socket handle, or anything else.
For an example, the FamilySplit pattern describes the circumstance under which it may be a good idea to split the instance data into multiple data structures.
-- StephenCheng
What worries me about the (void *) parameter is the loss of any type checking by the compiler. Opaque types in C do not require the use of void*. They can be simply achieved through a partial definition of the type, ie
struct InstanceDataType?; void SomeFunc? ( InstanceDataType? *this, ... );Here, the calling function has only a type-name to handle. They can not create instances of the type. They know nothing about the internal structure of the opaque type. This seems to meet your requirement above.
Additionally, you get some type-safety from the compiler. The (void *) version would not catch
int a; SomeFunc?(&a, ... );It would compile cleanly, and even run ... for a while. Tracking the fault could be very difficult. Using a named opaque-type means these errors are caught at compile time. If it 'is' possible to provide an int instead of the named type, then an explicit cast is needed to fore the interface. This stands out like a sore thumb and makes finding such instances much easier.
-- KeithDerrick