14

What is the major benefit of having pure POCO models? I get that Models should be clean and simple, but I tend to like to keep the maintenance of child objects within the model classes. For example if I have a ClassA and ClassB defined as follows:

public class ClassA
{
    public string MyProp { get; set; }
    public IEnumerable<ClassB> Children { get; }

    public void AddChild(ClassB newChild) { /*... */ }
    public void RemoveChild(ClassB child) { /* ... */ }
}

public class ClassB
{
    public string SomeProp { get; set; }
} 

Is there something inherently wrong with having the add and remove methods? Should I instead just expose the list and allow client code to add whatever passing the responsibility of simple data validations like not null, and not duplicate on to another class?

Any help is appreciated.Thanks.

  • I'd remove the Add/Remove methods unless they add some value, like translating a null ClassB argument into a NullObject pattern version of the object: AddChild(ClassB newChild) => Children.Add(newChild ?? new NullClassB()) – Graham Jun 5 '17 at 12:51
  • If you've ever dealt with the headache of ActiveRecord classes with hundreds of methods that may or may not be what you want at any given time I think it'd be easier to understand the appeal. – Casey Jun 5 '17 at 17:03
  • The main reason to avoid this particular design is because it goes against the .net design guidelines. It is completely arbitrary, but people expect the collection to have the mutating methods in it. – Frank Hileman Jun 5 '17 at 17:06
  • @Casey I'm not using the Active Record pattern, the add method is simply doing some minor data validation. The remove method is there because the collection is not exposed, they simply add and remove from an internal list. I have changed it though to use a different collection type that allows me to do the validation while still using the built in Add/Remove methods. – Jesse Jun 6 '17 at 12:53
41

Your two questions are unrelated.

What is the benefit to having pure POCO models?

A pure POCO is not dependent on some enterprisy framework, convention, [] thingy, or intimately connected to some object that is similarly dependent. In other words, the world can completely change around a POCO and it just keeps on doing what it does without caring. You can't break it by updating a framework, by moving it into a new system, or looking at it funny. It just keeps working. The only dependencies are the things it explicitly asks for.

POCO is nothing more than the POJO idea. The J was changed to a C because people look at you funny when you explain a concept that has Java in its name if those people are using C#. The idea is not dependent on language. They could have simply called it Plain Old Objects. But who wants to brag about using POO?

I'll let Fowler explain the origins:

The term was coined while Rebecca Parsons, Josh MacKenzie and I were preparing for a talk at a conference in September 2000. In the talk we were pointing out the many benefits of encoding business logic into regular java objects rather than using Entity Beans. We wondered why people were so against using regular objects in their systems and concluded that it was because simple objects lacked a fancy name. So we gave them one, and it's caught on very nicely.

martinfowler.com : POJO

As for your other question:

Is there something inherently wrong with having the add and remove methods?

I don't like A directly knowing about B. But that's a DIP thing not a POJO thing.

  • I had the direct dependency to B for simplicity's sake, Ideally these would both implement interfaces. But A still has a list of IInterfaceB. Is there something wrong with the AddChild method if the children are loosely coupled through interface references? – Jesse Jun 5 '17 at 4:59
  • 6
    I can do a whole host of silly things for simplicity's sake. What I don't like is A knowing about B. A doesn't use B so there isn't a need to define a proper A owned interface to talk to B through. As far as I can tell A is a collection. So A should deal with B through a <T> so it doesn't have to know a thing about it. – candied_orange Jun 5 '17 at 5:18
  • 2
    I have also seen “PODO” for “plain old data object” to avoid any sort of language specifier in the acronym. PODO sounds a little silly (kinda sounds like an epithet you’d hear on Tatooine, to me), more so than POJO or POCO I suppose, but significantly less silly than POO. – KRyan Jun 5 '17 at 11:29
  • 1
    I wonder how well Fowler's presentation would have gone if he had called them POO? – Oliver Jun 6 '17 at 13:31
3

With Add and Remove you are implementing Collection<T> features. Ask yourself why are you using IEnumerable<T> instead of List<T> or some other mutable class? Apparently it is not because your collection should be readonly.

The only reason I can think of is that you want to control what access methods you want to publish. In that case it would be nicer to create your own collection class, encapsulate a list, implement your select methods Add and Remove and implement IEnumerable<T>. Then use that instead of IEnumerable<T> for the type of your children collection.

But it seems to me List<ClassB> would probably just serve you well.

0

What does AddChild add to, and RemoveChild remove from? If it's from the database (or persistence store of whatever kind), you've sort of got an Active Record. Not necessarily always a bad thing, but it definitely gets you close to having to worry about frameworks, conventions, dependencies, etc., as @CandiedOrange mentions.

At the same time, what would be the point of avoiding a dependency from ClassA to ClassB (or at least InterfaceB) if they're all in the same application? In the real world domain that your application is modelling, things do depend on each other. Real-world objects do have collections of other objects that "belong" to them. It's entirely appropriate to represent those relationships in your code.

The only reason it gets even a little complicated is because it seems that you have a need to manage exactly how a ClassB becomes associated with and disassociated from ClassA. So you have a little behavior to implement. You can either implement it within the class (which is totally "legal"; see https://stackoverflow.com/a/725365/44586), or you can have some sort of separate class that contains that behavior. Do what makes the most sense for your individual circumstances.

In any case, POJO/POCO is really just OOP as it was meant to be, unadorned and unencumbered. Follow OOP principles and you'll be safe.

  • Really the AddChild is just checking for duplication, and null, and not allowing either. RemoveChild is there because to prevent backdoor adds the collection is exposed as an IEnumerable. It would only perform the standard remove from the collection though. – Jesse Jun 5 '17 at 16:04
  • 1
    Thanks for explaining. Yeah, that sounds like exactly the type of behavior that should be in a POCO, and definitely better than just exposing your underlying IEnumerable for callers to modify or replace at will. – John M Gant Jun 5 '17 at 16:19
  • I think Active Record is just a bad pattern. – Casey Jun 5 '17 at 17:04
  • 1
    @Casey, you won't get any argument from me about that. But I wouldn't argue if somebody wanted to use it either. Main point was if Jesse did intend to use a pattern like Active Record that integrates persistence with model definition, he would have all the problems CandiedOrange highlights, and wouldn't really qualify as a POCO, for what that's worth. But that's not what he's doing anyway. – John M Gant Jun 5 '17 at 17:10

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.