How to use and create DTOs is OOP world? - oop

What is the right way to create DTOs from business objects?
Who should be responsible for creating them? BO/DTO itself from BO/some static factory?
Where should they reside in code if I have, f.e. some core library and a specific service API library that I need DTO for? In core library next to BO(which seems incorrect)/in specific library?
If I have encapsulated fields in my BO how do DTO grab them? (obviously in case when BO is not responsible for creating DTOs)
As an example assume that I have some Person BO like this:
class Person
{
private int age;
public bool isBigEnough => age > 10;
}
I want age to be an internal state of Person but still I need to communicate my BO to some api. Or having private field in my class that I want to send somewhere already means that it should be public?
Are there any general considerations of how to use DTOs alongside business classes with encapsulated data?
___ Update:
In addition to approaches that #Alexey Groshev mentioned I came accross another one: we separate data of our BO class into some Data class with public accessors. BO wraps this data with its api(probably using composition) and when needed it can return its state as Data class as clone. So dto converter will be able to access Domain object's state but won't be able to modify it(since it will be just a copy).

There're multiple options available, but it would be difficult to recommend anything, because I don't know the details about your project/product. Anyway I'll name a few.
You can use AutoMapper to map BOs to DTOs and vise versa. I personally dislike this approach, because it's quite difficult (but possible) to keep it under control in medium/large sized projects. People don't usually bother to configure mappings properly and just expose internal state of their objects. For example, your isBigEnough would disappear and age would become public. Another potential risk is that people can map DTOs to/from EF/Hibernate objects. You can find some articles which explain why it's considered to be a bad practice.
As you suggested, a BO can create DTO by itself, but how would you implement this approach? You can add methods or factory methods to your entities, e.g. public PersonDto ToDto(). Or you can add an interface, e.g. public interface IDtoConvertable<T> { T ToDto(); }, and choose which entity or aggregate root will implement it. Your Person class would look like this class Person : IDtoConvertable<PersonDto> {... public PersonDto ToDto() {...} }. In both cases DTO namespace/assembly must to accessible by entities which sometimes can be a problem, but usually it's not a biggie. (Make sure that DTOs cannot access entities which is much worse.)
(C#) Another option is to return a delegate which creates DTO. I decided to separate it from (2), because entity doesn't really create DTO by itself, but rather exposes a functionality which creates DTO. So, you could have something like this public Func<PersonDto> ToDto() {...}. You might want to have an interface as in (2), but you get the idea, don't you? Do I like this approach? No, because it makes code unreadable.
As you see, there are more questions than answers. I'd recommend you to make a few experiments and check what works for you (your project) and what doesn't.

I think the answer to question 5 will address the other questions too.
Are there any general considerations of how to use DTOs alongside business classes with encapsulated data?
Remember, a DTO is solely to transfer data. Do not concern yourself with implementing any kind of rules in the DTO. All it is used for is to move data from one subsystem to another (NOT between classes of the same subsystem). How that data is used in the destination system is out of your control -- although as the God programmer you inherently know how it is going to be used, DO NOT let that knowledge influence your design -- and therefore there should be no assumptions expressed as behaviour or knowledge accessors -- so, no isBigEnough.

Related

DDD - Rehydrate aggregate roots?

All my entities are implementation of interfaces. Most of their properties are read-only.
My repository holds a reference to the library project where i hold all the interfaces, so technically speaking, the repository can save the aggregate root without knowing anything about it's de-facto implementation (something i believe to be a +1).
The problem here is: if most of the properties are read-only, how can I rehydrate a aggregate root without breaking OOP principles? should the repository hold a reference to the domain project and be aware of the concrete implementation of interfaces?
should the repository hold a reference to the domain project and be aware of the concrete implementation of interfaces?
As Evans describes in the Blue Book; the Repository is a role played by an implementation, to keep the application from mutating the underlying data directly. Similarly, the Aggregate Root is a role -- we don't let the application touch the actual entity, but instead just a limited part of it.
The implementation of the repository is part of the model, so it can know more about the specific entities being represented; including knowing how to extract from them a representation of state that can be handed off to your persistence component for storage.
To choose a specific context, let's pretend that we are modeling a TradeBook, and one of the interesting use cases is that of a customer placing orders.
In Java, the implementation of the Repository interface -- the bit that the application knows about, might look like
interface API.TradeBookRepository<TradeBook extends API.TradeBook> {
TradeBook getById(...);
void save(TradeBook);
}
interface API.TradeBook {
void placeOrder(...);
}
So the application knows that it has an access to a repository, but it doesn't know anything about the implementation but the promise that it
will provide something that supports placeOrder.
So the application code looks like:
API.TradeBookRepository<? extends API.TradeBook> repo = ....
API.TradeBook book = repo.getById(...);
book.placeOrder(...)
repo.save(book)
But a given repository implementation is usually coupled to a specific implementation of the book; they are paired together.
class LIFO.TradeBook implements API.TradeBook {
...
}
class LIFO.TradeBookRepository implements API.TradeBookRepository<LIFO.TradeBook> {
...
}
how can I rehydrate a aggregate root without breaking OOP principles?
To some degree, you can't. The good news is, at the boundaries, applications are not object oriented.
The thing you are putting into your durable store isn't an aggregate root; it's some representation of state. I tend to think of it as a Memento. What you really have are two functions - one converts a specific aggregate root implementation (ex: LIFO.TradeBook) to a Memento, the other converts a Memento to an aggregate root.
Key idea: you are probably going to want to change your domain model a lot more often than you are going to want to migrate the database. So the Memento needs to be designed to be stable -- in effect, the Memento is a message sent from the old domain model to the new one, so many of the lessons of message verioning apply.
Simply put, something somewhere in your application has to know about concrete implementations. If you really want to shield the repository implementation (not the contract) from knowing the concrete entities then that responsibility will simply have to fall on another collaborator (e.g. repository would delegate the rehydration to an abstract factory).
However, it's quite uncommon to have separate contracts for aggregates because you usually have a single implementation of these business concepts and there's usually no scenario where you would want to mock them in unit tests. Therefore, repository contracts and implementation are most of the time defined in terms of concrete aggregates.

Why would I create an interface for each mapper class?

In cases of MVC applications where the model is split into separate domain and mapper layers, why would you give each of the mapper classes its own interface?
I have seen a few examples now, some from well respected developers such as the case with this blog, http://site.svn.dasprids.de/trunk/application/modules/blog/models/
I suspect that its because the developers are expecting the code to be re-used by others who may have their own back-ends. Is this the case? Or am I missing something?
Note that in the examples I have seen, developers are not necessarily creating interfaces for the domain objects.
Since interfaces are contracts between classes (I'm kinda assuming that you already know that). When a class expects you to pass an object with as specific interface, the goal is to inform you, that this class instance expect specific method to be executable on said object.
The only case that i can think of, when having a defined interface for data mappers make sense might be when using unit of work to manage the persistence. But even then it would make more sense to simply inject a factory, that can create data mappers.
TL;DR: someone's been overdoing.
P.S.: it is quite possible, that I am completely wrong about this one, since I'm a bit biased on the subject - my mappers contain only 3 (+constructor) public methods: fetch(), store() and remove() .. though names method names tend to change. I prefer to take the retrieval conditions from domain object, as described here.

Worker vs data class

I have a data class which encapsulates relevant data items in it. Those data items are set and get by users one by one when needed.
My confusion about the design has to do with which object should be responsible for handling the update of multiple properties of that data object. Sometimes an update operation will be performed which affects many properties at once.
So, which class should have the update() method?. Is it the data class itself or another manager class ? The update() method requires data exchange with many different objects, so I don't want to make it a member of the data class because I believe it should know nothing about the other objects required for update. I want the data class to be only a data-structure. Am I thinking wrong? What would be the right approach?
My code:
class RefData
{
Matrix mX;
Vector mV;
int mA;
bool mB;
getX();
setB();
update(); // which affects almost any member attributes in the class, but requires many relations with many different classes, which makes this class dependant on them.
}
or,
class RefDataUpdater
{
update(RefData*); // something like this ?
}
There is this really great section in the book Clean Code, by Robert C. Martin, that speaks directly to this issue.
And the answer is it depends. It depends on what you are trying to accomplish in your design--and
if you might have more than one data-object that exhibit similar behaviors.
First, your data class could be considered a Data Transfer Object (DTO). As such, its ideal form is simply a class without any public methods--only public properties -- basically a data structure. It will not encapsulate any behavior, it simply groups together related data. Since other objects manipulate these data objects, if you were to add a property to the data object, you'd need to change all the other objects that have functions that now need to access that new property. However, on the flip side, if you added a new function to a manager class, you need to make zero changes to the data object class.
So, I think often you want to think about how many data objects might have an update function that relates directly to the properties of that class. If you have 5 classes that contain 3-4 properties but all have an update function, then I'd lean toward having the update function be part of the "data-class" (which is more of an OO-design). But, if you have one data-class in which it is likely to have properties added to it in the future, then I'd lean toward the DTO design (object as a data structure)--which is more procedural (requiring other functions to manipulate it) but still can be part of an otherwise Object Oriented architecture.
All this being said, as Robert Martin points out in the book:
There are ways around this that are well known to experienced
object-oriented designers: VISITOR, or dual-dispatch, for example.
But these techniques carry costs of their own and generally return the
structure to that of a procedural program.
Now, in the code you show, you have properties with types of Vector, and Matrix, which are probably more complex types than a simple DTO would contain, so you may want to think about what those represent and whether they could be moved to separate classes--with different functions to manipulate--as you typically would not expose a Matrix or a Vector directly as a property, but encapsulate them.
As already written, it depends, but I'd probably go with an external support class that handles the update.
For once, I'd like to know why you'd use such a method? I believe it's safe to assume that the class doesn't only call setter methods for a list of parameters it receives, but I'll consider this case as well
1) the trivial updater method
In this case I mean something like this:
public update(a, b, c)
{
setA(a);
setB(b);
setC(c);
}
In this case I'd probably not use such a method at all, I'd either define a macro for it or I'd call the setter themselves. But if it must be a method, then I'd place it inside the data class.
2) the complex updater method
The method in this case doesn't only contain calls to setters, but it also contains logic. If the logic is some sort of simple property update logic I'd try to put that logic inside the setters (that's what they are for in the first place), but if the logic involves multiple properties I'd put this logic inside an external supporting class (or a business logic class if any appropriate already there) since it's not a great idea having logic reside inside data classes.
Developing clear code that can be easily understood is very important and it's my belief that by putting logic of any kind (except for say setter logic) inside data classes won't help you achieving that.
Edit
I just though I'd add something else. Where to put such methods also depend upon your class and what purpose it fulfills. If we're talking for instance about Business/Domain Object classes, and we're not using an Anemic Domain Model these classes are allowed (and should contain) behavior/logic.
On the other hand, if this data class is say an Entity (persistence objects) which is not used in the Domain Model as well (complex Domain Model) I would strongly advice against placing logic inside them. The same goes for data classes which "feel" like pure data objects (more like structs), don't pollute them, keep the logic outside.
I guess like everywhere in software, there's no silver bullet and the right answer is: it depends (upon the classes, what this update method is doing, what's the architecture behind the application and other application specific considerations).

Why would I want to use Interfaces? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
I understand that they force you to implement methods and such but what I cant understand is why you would want to use them. Can anybody give me a good example or explanation on why I would want to implement this.
One specific example: interfaces are a good way of specifying a contract that other people's code must meet.
If I'm writing a library of code, I may write code that is valid for objects that have a certain set of behaviours. The best solution is to specify those behaviours in an interface (no implementation, just a description) and then use references to objects implementing that interface in my library code.
Then any random person can come along, create a class that implements that interface, instantiate an object of that class and pass it to my library code and expect it to work. Note: it is of course possible to strictly implement an interface while ignoring the intention of the interface, so merely implementing an interface is no guarantee that things will work. Stupid always finds a way! :-)
Another specific example: two teams working on different components that must co-operate. If the two teams sit down on day 1 and agree on a set of interfaces, then they can go their separate ways and implement their components around those interfaces. Team A can build test harnesses that simulate the component from Team B for testing, and vice versa. Parallel development, and fewer bugs.
The key point is that interfaces provide a layer of abstraction so that you can write code that is ignorant of unnecessary details.
The canonical example used in most textbooks is that of sorting routines. You can sort any class of objects so long as you have a way of comparing any two of the objects. You can make any class sortable therefore by implementing the IComparable interface, which forces you to implement a method for comparing two instances. All of the sort routines are written to handle references to IComparable objects, so as soon as you implement IComparable you can use any of those sort routines on collections of objects of your class.
The easiest way of understanding interfaces is that they allow different objects to expose COMMON functionality. This allows the programmer to write much simplier, shorter code that programs to an interface, then as long as the objects implement that interface it will work.
Example 1:
There are many different database providers, MySQL, MSSQL, Oracle, etc. However all database objects can DO the same things so you will find many interfaces for database objects. If an object implements IDBConnection then it exposes the methods Open() and Close(). So if I want my program to be database provider agnostic, I program to the interface and not to the specific providers.
IDbConnection connection = GetDatabaseConnectionFromConfig()
connection.Open()
// do stuff
connection.Close()
See by programming to an interface (IDbconnection) I can now SWAP out any data provider in my config but my code stays the exact same. This flexibility can be extremely useful and easy to maintain. The downside to this is that I can only perform 'generic' database operations and may not fully utilize the strength that each particular provider offers so as with everything in programming you have a trade off and you must determine which scenario will benefit you the most.
Example 2:
If you notice almost all collections implement this interface called IEnumerable. IEnumerable returns an IEnumerator which has MoveNext(), Current, and Reset(). This allows C# to easily move through your collection. The reason it can do this is since it exposes the IEnumerable interface it KNOWS that the object exposes the methods it needs to go through it. This does two things. 1) foreach loops will now know how to enumerate the collection and 2) you can now apply powerful LINQ exprssions to your collection. Again the reason why interfaces are so useful here is because all collections have something in COMMON, they can be moved through. Each collection may be moved through a different way (linked list vs array) but that is the beauty of interfaces is that the implementation is hidden and irrelevant to the consumer of the interface. MoveNext() gives you the next item in the collection, it doesn't matter HOW it does it. Pretty nice, huh?
Example 3:
When you are designing your own interfaces you just have to ask yourself one question. What do these things have in common? Once you find all the things that the objects share, you abstract those properties/methods into an interface so that each object can inherit from it. Then you can program against several objects using one interface.
And of course I have to give my favorite C++ polymorphic example, the animals example. All animals share certain characteristics. Lets say they can Move, Speak, and they all have a Name. Since I just identified what all my animals have in common and I can abstract those qualities into the IAnimal interface. Then I create a Bear object, an Owl object, and a Snake object all implementing this interface. The reason why you can store different objects together that implement the same interface is because interfaces represent an IS-A replationship. A bear IS-A animal, an owl IS-A animal, so it makes since that I can collect them all as Animals.
var animals = new IAnimal[] = {new Bear(), new Owl(), new Snake()} // here I can collect different objects in a single collection because they inherit from the same interface
foreach (IAnimal animal in animals)
{
Console.WriteLine(animal.Name)
animal.Speak() // a bear growls, a owl hoots, and a snake hisses
animal.Move() // bear runs, owl flys, snake slithers
}
You can see that even though these animals perform each action in a different way, I can program against them all in one unified model and this is just one of the many benefits of Interfaces.
So again the most important thing with interfaces is what do objects have in common so that you can program against DIFFERENT objects in the SAME way. Saves time, creates more flexible applications, hides complexity/implementation, models real-world objects / situations, among many other benefits.
Hope this helps.
One typical example is a plugin architecture. Developer A writes the main app, and wants to make certain that all plugins written by developer B, C and D conform to what his app expects of them.
Interfaces define contracts, and that's the key word.
You use an interface when you need to define a contract in your program but you don't really care about the rest of the properties of the class that fulfills that contract as long as it does.
So, let's see an example. Suppose you have a method which provides the functionality to sort a list. First thing .. what's a list? Do you really care what elements does it holds in order to sort the list? Your answer should be no... In .NET (for example) you have an interface called IList which defines the operations that a list MUST support so you don't care the actual details underneath the surface.
Back to the example, you don't really know the class of the objects in the list... neither you care. If you can just compare the object you might as well sort them. So you declare a contract:
interface IComparable
{
// Return -1 if this is less than CompareWith
// Return 0 if object are equal
// Return 1 if CompareWith is less than this
int Compare(object CompareWith);
}
that contract specify that a method which accepts an object and returns an int must be implemented in order to be comparable. Now you have defined an contract and for now on you don't care about the object itself but about the contract so you can just do:
IComparable comp1 = list.GetItem(i) as IComparable;
if (comp1.Compare(list.GetItem(i+1)) < 0)
swapItem(list,i, i+1)
PS: I know the examples are a bit naive but they are examples ...
When you need different classes to share same methods you use Interfaces.
Interfaces are absolutely necessary in an object-oriented system that expects to make good use of polymorphism.
A classic example might be IVehicle, which has a Move() method. You could have classes Car, Bike and Tank, which implement IVehicle. They can all Move(), and you could write code that didn't care what kind of vehicle it was dealing with, just so it can Move().
void MoveAVehicle(IVehicle vehicle)
{
vehicle.Move();
}
The pedals on a car implement an interface. I'm from the US where we drive on the right side of the road. Our steering wheels are on the left side of the car. The pedals for a manual transmission from left to right are clutch -> brake -> accelerator. When I went to Ireland, the driving is reversed. Cars' steering wheels are on the right and they drive on the left side of the road... but the pedals, ah the pedals... they implemented the same interface... all three pedals were in the same order... so even if the class was different and the network that class operated on was different, i was still comfortable with the pedal interface. My brain was able to call my muscles on this car just like every other car.
Think of the numerous non-programming interfaces we can't live without. Then answer your own question.
Imagine the following basic interface which defines a basic CRUD mechanism:
interface Storable {
function create($data);
function read($id);
function update($data, $id);
function delete($id);
}
From this interface, you can tell that any object that implements it, must have functionality to create, read, update and delete data. This could by a database connection, a CSV file reader, and XML file reader, or any other kind of mechanism that might want to use CRUD operations.
Thus, you could now have something like the following:
class Logger {
Storable storage;
function Logger(Storable storage) {
this.storage = storage;
}
function writeLogEntry() {
this.storage.create("I am a log entry");
}
}
This logger doesn't care if you pass in a database connection, or something that manipulates files on disk. All it needs to know is that it can call create() on it, and it'll work as expected.
The next question to arise from this then is, if databases and CSV files, etc, can all store data, shouldn't they be inherited from a generic Storable object and thus do away with the need for interfaces? The answer to this is no... not every database connection might implement CRUD operations, and the same applies to every file reader.
Interfaces define what the object is capable of doing and how you need to use it... not what it is!
Interfaces are a form of polymorphism. An example:
Suppose you want to write some logging code. The logging is going to go somewhere (maybe to a file, or a serial port on the device the main code runs on, or to a socket, or thrown away like /dev/null). You don't know where: the user of your logging code needs to be free to determine that. In fact, your logging code doesn't care. It just wants something it can write bytes to.
So, you invent an interface called "something you can write bytes to". The logging code is given an instance of this interface (perhaps at runtime, perhaps it's configured at compile time. It's still polymorphism, just different kinds). You write one or more classes implementing the interface, and you can easily change where logging goes just by changing which one the logging code will use. Someone else can change where logging goes by writing their own implementations of the interface, without changing your code. That's basically what polymorphism amounts to - knowing just enough about an object to use it in a particular way, while allowing it to vary in all the respects you don't need to know about. An interface describes things you need to know.
C's file descriptors are basically an interface "something I can read and/or write bytes from and/or to", and almost every typed language has such interfaces lurking in its standard libraries: streams or whatever. Untyped languages usually have informal types (perhaps called contracts) that represent streams. So in practice you almost never have to actually invent this particular interface yourself: you use what the language gives you.
Logging and streams are just one example - interfaces happen whenever you can describe in abstract terms what an object is supposed to do, but don't want to tie it down to a particular implementation/class/whatever.
There are a number of reasons to do so. When you use an interface, you're ready in the future when you need to refactor/rewrite the code. You can also provide an sort of standardized API for simple operations.
For example, if you want to write a sort algorithm like the quicksort, all you need to sort any list of objects is that you can successfuuly compare two of the objects. If you create an interface, say ISortable, than anyone who creates objects can implement the ISortable interface and they can use your sort code.
If you're writing code that uses a database storage, and you write to an storage interface, you can replace that code down the line.
Interfaces encourage looser coupling of your code so that you can have greater flexibility.
In an article in my blog I briefly describe three purposes interfaces have.
Interfaces may have different
purposes:
Provide different implementations for the same goal. The typical example
is a list, which may have different
implementations for different
performance use cases (LinkedList,
ArrayList, etc.).
Allow criteria modification. For example, a sort function may accept a
Comparable interface in order to
provide any kind of sort criteria,
based on the same algorithm.
Hide implementation details. This also makes it easier for a user to
read the comments, since in the body
of the interface there are only
methods, fields and comments, no long
chunks of code to skip.
Here's the article's full text: http://weblogs.manas.com.ar/ary/2007/11/
The best Java code I have ever seen defined almost all object references as instances of interfaces instead of instances of classes. It is a strong sign of quality code designed for flexibility and change.
As you noted, interfaces are good for when you want to force someone to make it in a certain format.
Interfaces are good when data not being in a certain format can mean making dangerous assumptions in your code.
For example, at the moment I'm writing an application that will transform data from one format in to another. I want to force them to place those fields in so I know they will exist and will have a greater chance of being properly implemented. I don't care if another version comes out and it doesn't compile for them because it's more likely that data is required anyways.
Interfaces are rarely used because of this, since usually you can make assumptions or don't really require the data to do what you need to do.
An interface, defines merely the interface. Later, you can define method (on other classes), which accepted interfaces as parameters (or more accurately, object which implement that interface). This way your method can operate on a large variety of objects, whose only commonality is that they implement that interface.
First, they give you an additional layer of abstraction. You can say "For this function, this parameter must be an object that has these methods with these parameters". And you probably want to also set the meaning of these methods, in somehow abstracted terms, yet allowing you to reason about the code. In duck-typed languages you get that for free. No need for explicit, syntax "interfaces". Yet you probably still create a set of conceptual interfaces, something like contracts (like in Design by Contract).
Furthermore, interfaces are sometimes used for less "pure" purposes. In Java, they can be used to emulate multiple inheritance. In C++, you can use them to reduce compile times.
In general, they reduce coupling in your code. That's a good thing.
Your code may also be easier to test this way.
Let's say you want to keep track of a collection of stuff. Said collections must support a bunch of things, like adding and removing items, and checking if an item is in the collection.
You could then specify an interface ICollection with the methods add(), remove() and contains().
Code that doesn't need to know what kind of collection (List, Array, Hash-table, Red-black tree, etc) could accept objects that implemented the interface and work with them without knowing their actual type.
In .Net, I create base classes and inherit from them when the classes are somehow related. For example, base class Person could be inherited by Employee and Customer. Person might have common properties like address fields, name, telephone, and so forth. Employee might have its own department property. Customer has other exclusive properties.
Since a class can only inherit from one other class in .Net, I use interfaces for additional shared functionality. Sometimes interfaces are shared by classes that are otherwise unrelated. Using an interface creates a contract that developers will know is shared by all of the other classes implementing it. I also forces those classes to implement all of its members.
In C# interfaces are also extremely useful for allowing polymorphism for classes that do not share the same base classes. Meaning, since we cannot have multiple inheritance you can use interfaces to allow different types to be used. It's also a way to allow you to expose private members for use without reflection (explicit implementation), so it can be a good way to implement functionality while keeping your object model clean.
For example:
public interface IExample
{
void Foo();
}
public class Example : IExample
{
// explicit implementation syntax
void IExample.Foo() { ... }
}
/* Usage */
Example e = new Example();
e.Foo(); // error, Foo does not exist
((IExample)e).Foo(); // success
I think you need to get a good understand of design patterns so see there power.
Check out
Head First Design Patterns

OOP class design, Is this design inherently 'anti' OOP?

I remember back when MS released a forum sample application, the design of the application was like this:
/Classes/User.cs
/Classes/Post.cs
...
/Users.cs
/Posts.cs
So the classes folder had just the class i.e. properties and getters/setters.
The Users.cs, Post.cs, etc. have the actual methods that access the Data Access Layer, so Posts.cs might look like:
public class Posts
{
public static Post GetPostByID(int postID)
{
SqlDataProvider dp = new SqlDataProvider();
return dp.GetPostByID(postID);
}
}
Another more traditional route would be to put all of the methods in Posts.cs into the class definition also (Post.cs).
Splitting things into 2 files makes it much more procedural doesn't it?
Isn't this breaking OOP rules since it is taking the behavior out of the class and putting it into another class definition?
If every method is just a static call straight to the data source, then the "Posts" class is really a Factory. You could certainly put the static methods in "Posts" into the "Post" class (this is how CSLA works), but they are still factory methods.
I would say that a more modern and accurate name for the "Posts" class would be "PostFactory" (assuming that all it has is static methods).
I guess I wouldn't say this is a "procedural" approach necessarily -- it's just a misleading name, you would assume in the modern OO world that a "Posts" object would be stateful and provide methods to manipulate and manage a set of "Post" objects.
Well it depends where and how you define your separation of concerns. If you put the code to populate the Post in the Post class, then your Business Layer is interceded with Data Access Code, and vice versa.
To me it makes sense to do the data fetching and populating outside the actual domain object, and let the domain object be responsible for using the data.
Are you sure the classes aren't partial classes. In which case they really aren't two classes, just a single class spread across multiple files for better readability.
Based on your code snippet, Posts is primarily a class of static helper methods. Posts is not the same object as Post. Instead of Posts, a better name might be PostManager or PostHelper. If you think of it that way, it may help you understand why they broke it out that way.
This is also an important step for a decoupling (or loosely coupling) you applications.
What's anti-OOP or pro-OOP depends entirely on the functionality of the software and what's needed to make it work.