I have an interface ICondition which only defines a single method, IsConditionMet

This works well as it is the only information the parent entity needs from its conditions.

However, there is a situation where a user needs to remove a specific condition from its parent that I am struggling to find a elegant way to implement.

Both classes that implement this interface happen to use a GUID identifier at the moment, but there's no inherent reason why this would need to be the case and could be subject to change; the two classes don't really have anything in common other than being predicates.

One possible solution could be to override the Equals method in the classes and return true when passed the ID. However, to me, this seems to not quite mesh with the intent of the method and violates the principal of least astonishment.

Another solution could be to create an IIdentifiable interface with a method, IdentifiesAs then have ICondition inherit from it. This however seems like it goes against the ISP spirt as any implementor of ICondition must now implement IIdentifiable too.

Does anyone have any guidance for sticking to the ISP while being able to uniquely identify a object? Am I overthinking this?

  • It seems like you need more than just IsConditionMet() to be usable. add more! – Ewan May 14 '18 at 15:28
  • Do all conditions have an ID? My experience would lead me to assume they do. If they all do, what would be so bad about putting IdentifiesAs directly on the ICondition interface? – Mike Supports Monica May 14 '18 at 15:39
  • @MIke actually, there is a third that doesn't (But it's a mock used for unit testing) – TheCatWhisperer May 14 '18 at 16:13
  • How does the user want to identify the condition? And remove it from where? – Stop harming Monica May 14 '18 at 16:54
  • @Goyo Parent.RemoveCondition("ID") – TheCatWhisperer May 14 '18 at 17:01

Assuming that I've understood you, you have a situation where: 1. Currently you have a couple of types that implement IsConditionMet and IdentifiesAs. 2. You see a situation where in the future, you may need types that only implement IsConditionMet.

Assuming that's correct, then follow the YAGNI (you ain't going to need it) principle: when you need to handle types that only implement IsConditionMet, deal with that situation at that time.

However, there is away that you can plan for this, without creating unnecessary code now: good names.

Create an IIdentifiableCondition type now:

interface IIdentifiableCondition
    bool IsConditionMet(...);
    Guid IdentifiesAs { get; }

Then in the future, when you just need IsConditionMet, add a parent interface, thus:

interface ICondition
    bool IsConditionMet(...);

interface IIdentifiableCondition : ICondition
    Guid IdentifiesAs { get; }
|improve this answer|||||
  • Good answer, though this would still break my unit test where I test the logic associated with parent which has a dependency on a mock ICondition, but no need for an ID – TheCatWhisperer May 15 '18 at 12:20
  • And I dont have any IdentifiesAs it is just one possible solution I was putting forward – TheCatWhisperer May 15 '18 at 12:21

From the comments to your original post, it is obvious that your ICondition has to be qualified by the identifier in some form or other.

interface ICondition<ID> {
  ID GetId();
  bool IsConditionMet();

This abstracts away the nature of the ID, and closes the contract that the ICondition must meet: that it both indicate that the condition is met and be able to identify itself for possible removal.

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.