I just started learning OOP and I'm finding it really hard to decide where functionality belongs. Let's use a down
vote in SO for our example:
When we cast one, the following must happen in a transaction:
- Decrement the voter's
rep
and downVotes
count.
- Decrement the recipient's
rep
.
- Decrement the post
score
.
So...
- How do we determine which action belongs to which object?
- Where would such functionality live? In the DAO layer, services layer, or the actual objects themselves?
It becomes increasingly tricky when objects interact with each other, such as in my example. It's often hard to decide what function belongs to what object and so on...
Take a look at SOLID principles of OO design, Coupling & Cohesion.
OO can be used in many places, it is not limited to e.g. your Business Layer. You can write your Javascript object-oriented.
I'd model your example SO domain similar to this (in C#). This is idealistic OO code, and in real world some compromises would be made, such as making fields public for my ORM. What I am trying to show - each object is responsible for its data, noone else can change it directly; they must ask that object to do something, by calling one of the public methods.
public class User
{
private int _reputation;
private int _downvotes;
public void Downvote(Post post)
{
DecreaseReputation();
IncrementDownvotes();
post.Downvote();
}
public void RegisterDownvote()
{
DecreaseReputation();
}
private void DecreaseReputation()
{
_reputation--;
}
private void IncrementDownvotes()
{
_downvotes++;
}
}
public class Post
{
private int _score;
private User _poster;
public void Downvote()
{
DecreaseScore();
_poster.RegisterDownvote();
}
private void DecreaseScore()
{
_score--;
}
}
This is not an easy question to answer and sounds more like a design-pattern question than an OOP question per se. In the case of SO (I am making an assumption based on assumed design patterns for their site), all the "layers" of the design-pattern are involved in what you are calling a "transaction" (not a DB term I assume the way you are using it). The UI layer or View accepts the "down vote" and makes a what appears to be an ajax request most likely to a layer that handles business rules, which determines what actually happens when a "down vote" is cast against a user. At that point, the business layer makes requests of the data layer to update a database somewhere to update the user's score, reputation, etc. This also may be performed a little bit differently using web services, who knows what's under the hood here at SO. As far as OOP; I am sure there is a lot of OOP under the hood, everywhere, in all the layers, scripting and other languages perhaps, but I would imagine that in the case of your example, SO is not passing around a "User" class object when a vote is cast; there is no need to.
Here is the very popular MVC design pattern for example: http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller