Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

POCOs and utility methods

Tags:

c#

poco

Lets assume that I have a POCO class that contains foos and bars:

public class Poco {
  public IEnumerable<Foo> Foos { get { return foos; } }
  public IEnumerable<Bar> Bars { get { return bars; } }

  private List<Foo> foos;
  private List<Bar> bars;
}

In my example I need to be able to add and remove foos and bars:

public class Poco {
  public IList<Foo> Foos { get { return foos; } }
  public IList<Bar> Bars { get { return bars; } }

  private List<Foo> foos;
  private List<Bar> bars;
}

But lets say that I also need the (arbitrary) constraint that there must be one foo per bar and also one bar per foo.

public class NotAPocoAnyMore {
  public IEnumerable<Foo> Foos { get { return foos; } }
  public IEnumerable<Bar> Bars { get { return bars; } }

  private List<Foo> foos;
  private List<Bar> bars;

  public void Add(Foo f, Bar b) {...}
  public void Remove(Foo f, Bar b) {...}
}

My question is this: Am I getting to worked up about trying to keep a POCO simple and not give it any utility methods? The first example POCO is nice because it is immutable, and POCOs have other advantages. However, I can't see a way to keep the class a POCO and still have ways to access and modify the contents in a controlled way (at least not a way that doesn't seem over-kill).

Some thought that I have had:

Nested modifying class

public class Poco {
  public IEnumerable<Foo> Foos { get { return foos; } }
  public IEnumerable<Bar> Bars { get { return bars; } }
  public PocoModifier Modifier { get { ... } }

  private List<Foo> foos;
  private List<Bar> bars;

  public class PocoModifier {
    private readonly Poco toModify;
    public void Add(Foo f, Bar b) {...}
    public void Remove(Foo f, Bar b) {...}
    ...
  }
}

Public nested class? No thanks! Also it really is just the same as the non-POCO class just with a little more nesting.

Using access modifiers

public class Poco {
  public IEnumerable<Foo> Foos { get { return foos; } }
  public IEnumerable<Bar> Bars { get { return bars; } }
  public PocoModifier Modifier { get { ... } }

  internal List<Foo> foos;
  internal List<Bar> bars;
}

public class PocoModifier {
  private readonly Poco toModify;
  public void Add(Foo f, Bar b) {...}
  public void Remove(Foo f, Bar b) {...}
  ...
}

Slightly better, but requires a whole unit of deployment for each POCO.

like image 275
Jonny Avatar asked Apr 15 '14 20:04

Jonny


People also ask

What is a utility method?

- Quora Answer (1 of 2): Utility methods perform common, often re-used functions which are helpful for accomplishing routine programming tasks. Examples might include methods connecting to databases, performing string manipulations, sorting and searching of collections of data, writing/reading data to/f...

Can you call public utility methods from a trigger?

"You can call public utility methods from a trigger." What is an utility method? Thank you. Utility classes are helper classes that consisits of reusable methods. From triggers we can call methods in such public classes.

What is the difference between utility class and apex class?

Here, EmailManager is another apex class and sendEmail () is one of its method. If it helps, mark it as best answer. Utility classes are helper classes that consisits of reusable methods.


2 Answers

It sounds like your data would be better modeled by something that naturally pairs a Foo with a Bar.

public class Poco {
  public IList<Tuple<Foo, Bar>> FooBars { get { return fooBars; } }

  private List<Tuple<Foo, Bar>> fooBars;
}

Unless for some strange reason the Foos and Bars are completely separate except for the requirement that their count is the same. Then I like your third example...

public class NotAPocoAnyMore {
  public IEnumerable<Foo> Foos { get { return foos; } }
  public IEnumerable<Bar> Bars { get { return bars; } }

  private List<Foo> foos;
  private List<Bar> bars;

  public void Add(Foo f, Bar b) {...}
  public void Remove(Foo f, Bar b) {...}
}

PocoModifier adds unnecessary complexity, in my opinion. And nested classes should generally not be public (so if you have the class at all, make it separate like in your last example).

If you need a POCO to work with as well (e.g. to expose that publicly to people using your code as a library, while keeping other logic internal), you might create a plain POCO and then map it to NotAPocoAnyMore with AutoMapper (or similar).

public class Poco {
  public IList<Foo> Foos { get; set; }
  public IList<Bar> Bars { get; set; }
}
like image 190
Tim S. Avatar answered Oct 31 '22 22:10

Tim S.


POCOs only represents a unit of data/information. Once you start enforcing rules either as a constraint or as a way for better organizing your data, you start defining behaviour of your data. Suddenly, you are not dealing with POCOs anymore and It becomes a full blown Data Structure.

How you implement this is up to you. If you want to work with POCOs, you can segregate your data and the behaviour by using Helpers/Extensions or whatever you fancy or you can build your own Data Structure by combining the data and it's behaviour in a single entity.

There is nothing wrong with either of them and while some people prefer working with POCOs, I usually prefer working with Data Structures that encapsulates data and it's behaviour in a single entity.

like image 40
Shalin Ved Avatar answered Nov 01 '22 00:11

Shalin Ved