Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TDA(Tell, Don’t Ask) principle of OOP #83

Open
JinYouZhen opened this issue Jun 15, 2022 · 1 comment
Open

TDA(Tell, Don’t Ask) principle of OOP #83

JinYouZhen opened this issue Jun 15, 2022 · 1 comment

Comments

@JinYouZhen
Copy link

JinYouZhen commented Jun 15, 2022

To execute an action without requesting the necessary data, the action and data must be together. Oriented Object Programming (OOP) is characterized by combining data (fields) and related actions (methods) into classes, and the TDA principle is a tool that makes good use of them.

The UserAccount class below is composed of email and password data and has the behavior Save for saving user accounts in a database. A field representing data and a method representing an action are located in the same class, so there is no need to request the data separately. It follows the TDA principle.

The TDA principle is a tool that emphasizes the characteristics of OOP, but from a different perspective, there is a problem.
`
public class UserAcccount{
private string email;
private string password;
... // field initialization

public void Save()
{
    ... // stored in database
}

}
`

Open/Closed Principle(OCP)

Imagine that there is a request for saving the user account as a file instead of stored in the database. The internal code of method Save must be modified to implement this request. It violates the OCP which states that software entities(classes, modules, methods, etc.) should be open for extension, but closed for modification.

Look at the code below. DBStore class has the Save method, and data that are to be stored in the database is stored in instance UserAccount. This is the case of asking for data without not saying what to do. This violates the TDA principle. However, the new class FileStore can be written for the use of saving the user account as a file. The new function is for saving data as a file without deleting or modifying the code(Thanks for not violating OCP).

`public class UserAcccount
{
// property initialized
...

public string Email { get; }

public string Password { get; }

}

public class DbStore
{
public void Save(UserAccount account)
{
string email = acccount.Email; // TDA violation
string password = account.Password;

    // stored in database
    ...
}

}`

Single Responsibility Principle(SRP)

Now let's include a function for sending an email through the user’s email address without violating the TDA principle. The method SendEmail violates the OCP. Also, the class UserAccount has to take two roles: saving accounts and sending emails.
If only one of them is changed, code modification is necessary. The reason for modifying the class violates the SRP(Every module, class, or function in a computer program should have responsibility for a single part of that program’s functionality, and it should encapsulate that part).

`public class UserAcccount
{

private string email;
private string password;
...

public void Save()
{
    ...
}

public void SendEmail()
{
  ...
}

}
`

The way to follow SRP is simple. In the case of OCP above, just as you create a new class FileStore, we just need to make a new class named EmailService for sending emails. This class would store user email data in the UserAccount instance for mail delivery. This solution violates TDA but follows SRP.

WHY DO WE HAVE TO FOLLOW OCP AND SRP

According to the TDA principle, actions should be added to the class to which the relevant data belongs. When a behavior is added one by one, the class would become a bloated class and it will more likely violate SRP. All actions related to a particular data are to be processed in the class to which that data belongs. However, it is unlikely to make the class a God object(objects of classes that know too much or do too much and hence make your code tightly coupled and difficult to maintain).
As a developer follows OCP and SRP more and more, the number of actions in the class tends to decrease, while the number of classes tends to increase. Rather than using classes with many behaviors (coarse-grained), we go to small-grained directions (small-grained) for many classes. This can be led to a problem of selecting the class, but it can be solved by using namespace and nested class.

Conclusion

The TDA principle makes good use of OOP characteristics that combine data and related actions into classes. However, the more developers follow TDA principles, the more OCP and SRP are violated. Developers may finally meet God object. We should ask for the data we need and sometimes say what we want to do. When we are at a crossroads between these two, we should consider which way is the shortcut.

参考
http://martinfowler.com/bliki/TellDontAsk.html
http://c2.com/cgi/wiki?TellDontAsk
http://coding-is-like-cooking.info/2013/05/tell-dont-ask-object-oriented-design/
https://pragprog.com/articles/tell-dont-ask

@JinYouZhen
Copy link
Author

only certain parts of my codes are recognized as sourcecode.. don't know how to fix this problem sorry:(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant