Should entities implement interfaces?
Asked Answered
T

5

10

I personally don't have my entities implement interfaces. For a Task class I wouldn't have ITask that just had the same properties defined on it.

I've seen it done a few times though, so I'm wondering where that advice comes from, and what benefits you get from it.

If you're using an ORM then the argument that says "I can change my data access" is irrelevent, so what other reason is there for doing this?

UPDATE:
A good point was made in the comments about INotifyPropertyChanged. That wasn't my point though - I'm talking about having something like this:

public interface ITask
{
    int Id { get; set; }
    string Description { get; set; }
}

public class Task : ITask
{
    public int Id { get; set; }
    public string Description { get; set; }
}
Touchmenot answered 17/11, 2010 at 11:58 Comment(4)
One word: INotifyPropertyChangedAnisaanise
This must need some more tags.Dieball
@Dieball Please feel free to re-tag if you like. I didn't want this to be language-specific and "best-practices" isn't advised as a tag any more so wasn't sure what else to use.Touchmenot
No one used the term 'entity' in this sense in Java, so I'm thinking this is C#-specific.Dieball
T
3

I went down this road once (interfaces for value objects). It was a royal pain in the backside, I recommended against it. The common arguments for it are:

Mocking: They are value objects. Nought to mock. Plus mocking ends up being a large pain than either writing a builder (in Java) or using the named arguments stuff in C#.

Readonly views: I must admit I still prefer to make something immutable by default, only making it mutable if absolutely required.

Hidden functionality: Generally scope has covered this one for me.

Trace answered 18/11, 2010 at 9:40 Comment(5)
Not forgetting also that XmlSerializer flat out refuses to serialize interfaces or deserialize to an interface.Disorder
How you make the second point (Readonly views) without using Interface?Richellericher
I generally make things immutable by default. Else clone before handing to something "unsafe" or supply a read-only interface.Trace
Is it a yes or no?Nightgown
It is a no. Don't create interfaces for dtos.Trace
I
1

The major benefit of this is that it is a way of exposing your entity as a "read-only" version (as long as your interface does not expose setters of course).

Inwardly answered 17/11, 2010 at 12:1 Comment(1)
is it a yes to do?Nightgown
S
1

We're doing quite a bit of unit testing and so often want to mock out things we're not testing. Although I don't like it, we've ended up using interfaces all over the place because it makes it a lot easier to mock things.

In theory most of the mocking frameworks can mock normal classes too, but in practice this has caused us issues because we sometimes do clever things with reflection and the type of the mocked class isn't the same as the original. So doing:

var myTask = MyIoCProvider.Get<Task>();
var taskType = typeof(myTask);

Was unpredictable. Whereas:

var myTask = MyIoCProvider.Get<ITask>();
var taskType = typeof(myTask);

Gives you as taskType that IS definitely derived from ITask.

So interfaces just give us a way of making our system more mockable.

Slesvig answered 17/11, 2010 at 12:47 Comment(2)
I see. However why would you return entities from your IoC container? Are we talking about unit testing of full-on data-and-behaviour domain objects that have dependencies on other domain objects, and you want to mock those dependencies?Touchmenot
In our case we have a distinction between data objects like "Task" and business logic objects like "TaskAssignmentManager". The pure data objects have no logic in them so don't need mocking, IoC or interfaces. If we had domain objects that had both logic and data I think we'd end up with interfaces on them.Slesvig
B
0

If you were thinking in terms of using DomainEvents than data structures such as the task really do need to implement an interface

public interface IDomainEvent
{
   Guid EventId { get; }
   Guid TriggeredByEvent { get; }
   DateTime Created { get; }
}

public class OrderCancelledEvent : IDomainEvent
{
   Guid EventId { get; set; }
   Guid TriggeredByEvent { get; set; }
   DateTime Created { get; set; }
   // And now for the specific bit
   int OrderId { get; set; }
}

Or similarly if you have a common data access layer that may need to take in a standard base class of IEntity but I wouldn't have an interface for each type if it is just a data structure as you describe in your post.

When you are handling Domain Objects that actually expose behaviour you may then want to have an interface for unit testing.

Breadth answered 17/11, 2010 at 16:21 Comment(0)
O
0

I think some programmers just use interfaces, because they heard interfaces are good so they ended using them everywhere without thinking about actual pros and cons.

Me personally, I never use interfaces for entities that only represent a piece of data like db row for example.

Overplay answered 17/2, 2021 at 13:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.