What is the purpose of ICheckValid
interface? Do you call check_valid
elsewhere? In my opinion, since the frame_number
seems to be in fact a read-only property of a Frame
, why it would be wrong to verify its consistency right in the constructor without any additional interfaces for that? (Constructors are supposed to produce consistent objects and are thus free to validate incoming parameters however they like.)
However, rather than to ask how to properly validate this field, it might be better to ask why indeed you need the frame_number
property in the Frame
? It seems like this is an index of this item in some array - you may just use the index, why store it in the Frame
? You may want to write some if/else logic later, such as:
if (frame_number == 10) {
// some rules
} else {
// other rules
}
However, this is unlikely a SOLID approach as you would probably end up writing this if/else statements in many parts of the Frame
. Rather, you may create a base class FrameBase
, define much of the logics there plus some abstract methods to be implemented in OrdinaryFrame
and TenthFrame
, where you would define different rules. This would enable you to avoid frame_number
altogether -- you would just create nine OrdinaryFrames
and one TenthFrame
.
As for critique: your code seems to abstract balls and frames, but ignores 'throws', or 'rolls' for some reason. Consider a need to add trajectory information of each roll, you would need to change the IFrame
interface, adding something like void SetThrowTrajectory(int throwNumber, IThrowTrajectory trajectory)
. However, if you abstract throws away in an e.g. IBallRoll
, the trajectory-related functionality would easily fit there (as well as some Boolean computed properties, e.g. IsStrike
, IsSpare
).