You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
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
}
`
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 instanceUserAccount.
This is the case of asking for data without not saying what to do. This violates the TDA principle. However, the new classFileStore
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 class DbStore
{
public void Save(UserAccount account)
{
string email = acccount.Email; // TDA violation
string password = account.Password;
}`
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 classUserAccount
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
{
}
`
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 namedEmailService
for sending emails. This class would store user email data in theUserAccount
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
The text was updated successfully, but these errors were encountered: