Improve System OOP abstraction to deal with complex requirements, from: http://www.nowamagic.net/librarys/veda/detail/1373
Someone asked me how to build a better class and how to use object-oriented design, you can also ask why I read so many object-oriented and design patterns that I always write process-oriented code when I use them. I always answer these questions, but I don't know. Actually, I don't know.
Although I always open my mouth and open my mouth to objects, I always talk about this bit of XXX model after seeing a problem, but most of the time I encounter a problem, I am still blank, I don't know how to analyze and design and implement good object-oriented features. So I just want to talk about how I practice object-oriented, which is useful to myself but not necessarily to you. Well, back to the question.
Looking back at the development history of programming methods, I think it's nothing more than abstract.
From the earliest child routines used in assembly languages to structured programming, to object-oriented, component-oriented, and service-oriented. I think they are constantly improving the abstraction layer. So the programming method is not good or bad, only suitable and not suitable. In the Assembly era, the problem scale is very small, so we do not need to be too strong in abstract capabilities. In modern software projects, the scale of problems is very large, and there are many things to consider (although the pure technical content is not necessarily high in the compilation age ), we must use a higher abstraction level method to match the scale of our problem.
The emergence of object-oriented programming methods is almost the same, therefore, when using object-oriented method development, we aim to improve the abstract level (for example, some people have proposed that object-oriented method is not enough to match the abstract level of parallel soft computing, so I no longer teach object-oriented, but instead teach functional programming ).
I think a good way to improve the abstraction level is to use code to talk to people, use code to express your thoughts, and form "Concepts" in code ", or code is used to transmit knowledge. I put a special emphasis on the concept by adding quotation marks. In the following article, I will talk about what is the concept mentioned here. I don't want to talk too much on the surface. Let's do it.
Note: The code in this article is just to illustrate some problems or phenomena, without considering the rationality of the business. You can identify and think about it with your own business code.
Method Parameters
I don't know if you have written or seen the following code:
bool IsValid(string userName, string password, string email, int status);
If you have seen it before, then you will lose the opportunity to raise the abstract level. Robert Martin mentioned in "clean code" that there should not be too many method parameters. If there are too many parameters, we should take a special look. When we look at the above method parameters, we find that these parameters should belong to the same thing, but we do not. Similar to string and integer types, the abstract level is too low and there is no domain meaning. In addition, we found that the parameter and method name isvalid of the above method are not at the same abstract level. When we read the isvalid method, we cannot even understand its purpose at once: Oh, is this method used to check the validity of the user name, password, email, and status? Well, it's not always true. If we look at these parameters, we may write the code like this:
Bool isvalid (User user); public class user {Public String username {Get; set;} Public String password {Get; set;} Public String email {Get; set ;} // here, an enumeration can be created to improve the Abstraction Level-_-Public int status {Get; Set ;}}
Oh, after seeing this method, I know that this method is used to check the validity of the user. In addition, we have created a concept "user ", we aggregate a pile of scattered data into a new object and pass you a knowledge.
Don't be infatuated with brother
Then we can go to the isvalid method to see the following:
bool IsValid(User user){ if(user.UserName.Length > 0 && user.Email.Contains("@")){ //.... } //...}
We found that the internal task of this method is to constantly ask the user object, explore the internal status of the user object, and then make some judgments. It is not good to explore others' privacy. Such a strong dependence on others' internal states violates the object-oriented encapsulation principle. If a piece of code constantly explores the internal status of another object and makes some judgments, we should think about whether the queried object lacks a concept? Or this code should belong to the object to be asked, rather than the current object:
public class User{ public bool IsValid() { if(userName.Length > 0 && email.Contains("@")) { //.... } //... }}
Here is a group
Sometimes we find that some code inside the method is entangled around a central point. There is a gap with other code in the method. The most important thing is that this code seriously affects the readability of the entire method. With this code, the method becomes longer and the method is more difficult to understand. At this time, we should sort the code inside the method and check whether some code is to do one thing (this may happen when the method is just written, code for the same purpose is put together, but as time passes, the continuous addition of new code may violate this principle ). For example, the isvalid method above may be implemented as follows:
public class User{ public bool IsValid() { if(userName.Length > 0 && (email.Contains("@") && (email.EndsWith(".com") || email.EndsWith(".biz")...))) { //.... } //... }}
That long string & | isn't it to verify the validity of the email? This is a mess because of its existence. If we can further improve the abstract level: extract a group of code to a method and describe the method itself with the method name:
public class User{ public bool IsValid() { if(userName.Length > 0 && IsEmailValid()) { //.... } //... } bool IsEmailValid() { return email.Contains("@") && (email.EndsWith(".com") || email.EndsWith(".biz")...)); }}
Not only has the abstract level of this group of Code been improved, but isvalid suddenly becomes more elegant and knowledgeable (but the group of code still exists, but is hidden behind the abstraction, forget whether there is such a famous saying: Every beautiful interface is followed by a dirty implementation [joke]).
Split Personality
I have never encountered such code. There are five methods in a class. Three Methods access the attributes A, B, and C, and the other two access the attributes D, E, and F. There seems to be a vaguely visible line that splits this class into two. Sometimes this line is not very obvious, and there may be some crossover. This is actually similar to the preceding extraction method. We only have a higher level than the method: the lack of a type to separate this part of the code. Looking at the above user class, we found that there are several methods that are always centered around email, not very concerned about other things of the user class:
public class User{ public bool IsValid() { if(userName.Length > 0 && IsEmailValid()) { //.... } //... } bool IsEmailValid() { return email.Contains("@") && (email.EndsWith(".com") || email.EndsWith(".biz")...)); } public string EmailAddress() { return string.Format("\"{0}\"<1>",userName,email); } private string Convert() { if(email.IndexOf(‘#‘) != -1) { return email.Replace(‘#‘,‘@‘); } }}
I think we may lack the concept of email, so that we can encapsulate these methods and their attributes to be used:
public class User{ private Email email; public bool IsValid() { if(userName.Length > 0 && email.IsEmailValid()) { //.... } //... } } public class Email{ private string address; bool IsEmailValid() { return address.Contains("@") && (address.EndsWith(".com") || address.EndsWith(".biz")...)); } public string EmailAddress(string userName) { return string.Format("\"{0}\"<1>",userName,email); } private string Convert() { if(email.IndexOf(‘#‘) != -1) { return address.Replace(‘#‘,‘@‘); } }}
Okay. Let's talk about that much. There are still many examples of similar improvements to the abstraction layer, simply by reorganizing the code to form some concepts and passing the knowledge of the field to the person who reads the code. What I want to talk about is that object-oriented design may be really difficult and requires a wealth of experience, but object-oriented programming is not difficult. We only need to have a heart to keep improving. The code is not written out and then put there, so we don't need to worry about it. We need to take care of our code from time to time, observe it, and then continue to engrave it.
The target audience is very similar to the big mom's egg. Spread the pie, and each small piece of the pie is very thin, and then it is easy to cook.