Scud (Flying Cloud Xia) http://www.jscud.com reprinted please note the author
[Use of null interfaces]
When an interface is used, there are two scenarios for an empty interface:
1. similar to cloneable and serializable, they often make a tag to indicate that a function is required. of course, you can also use this to indicate that your class has a certain function and has implemented one of your interfaces.
2. your interface inherits other interfaces (not empty), and your interface itself does not declare a function. in this case, you generally do not want the user to use the parent interface as the parameter type, because they may have different purposes. At this time, you can use an empty interface to implement this.
In the first case, we will not talk more about it. Search for articles about cloneable and serializable, And we will know a lot about it.
Let's look at the following code:
Public interface text { String gettext (); }
Public interface sqltext extends text { } |
We can see that the text interface is used to return a string. sqltext is an empty interface that inherits the text interface. that is to say, sqltext is also a type of text. however, we can know that any string is not necessarily an SQL string. Therefore, a sqltext interface is declared to use the current string of the table name as an SQL string. your function can be declared as follows:
Public void doquery (sqltext asqltext)
Instead
Public void doquery (Text atext)
To avoid ambiguity, you can see at a glance that an SQL string should be passed in.
[Too many inheritance levels]
Generally, do not have too many inheritance layers, otherwise users may hate it and it will be very troublesome to find a function. Many Java language check tools recommend that you do not have more than three inheritance layers.
[Has A, is a, do not abuse inheritance]
"I am an MP3" and "I have an MP3" are easy to tell. however, in practical applications, I often think of "I have an MP3" as "I am an MP3", or I relaxed my requirements for laziness and convenience, I was even complacent and found a shortcut. (SCUD has done this before ).
I have done this before: My logic class directly inherits my database category class, so that I can directly access it in the logic class:
Public mylogic extends mydba
Alogic. getint ("click "); Alogic. getstring ("name "); |
It seems very convenient, but your logic class is firmly tied to DBA, which is a very bad practice. Now I declare:
Public mylogic
Mydba adba;
Adba. getint ("click "); Adba. getstring ("name "); |
In fact, the Code is not changed much, but your logic class is not firmly tied to the DBA. Why not.
In fact, this phenomenon may often occur among developers. We should avoid it as much as possible. Let's look at an example below:
// A class for storing paging information
Public class pageinfo { Private int page; Private int pagecount; Private int recperpage; Private int reccount;
// Get, Set Method list... } |
Generally, pageinfo needs to be passed to Dao for paging query, calculation of total records, and total number of pages in Dao. in the logic class, the transferred paging information data is pushed to formbean or action.
Maybe you will think so. If my action or formbean inherits pageinfo, wouldn't it save a lot of trouble.
Do not do this. Not all actions require paging information. Your formbean and pageinfo have no inheritance relationship. That is to say, formbean has a pageinfo, but not is a pageinfo.
[Keep appearance/Behavior consistent]
Consistency is easy to understand. For example, if you use size () to get the size of a list, you can use size () in all List classes to get its size, this is the same appearance.
Consistent appearance makes it easier for users to use your function library. You don't have to remember several different function names that indicate the same function. Or a few functions with the same name but different functions.
Behavior consistency is relatively difficult to achieve, but a good designer will certainly make his achievements consistent, rather than unexpected behavior, is not a set of forcible behavior.
Let's look at the following code:
Import java. util. hashmap; Import java. util. Map;
Class userinfo { Private string realname;
Public userinfo (string sname) { This. realname = sname; }
Public void setname (string sname) { This. realname = sname; } Public String getname () { Return this. realname; } }
Public class mytest {
Map userinfomap = new hashmap ();
Public void setuserinfo (string sname, userinfo ainfo) { Userinfomap. Put (sname, ainfo );
Userinfomap. Put (ainfo. getname (), ainfo ); }
Public userinfo getuserinfo (string sname) { Return (userinfo) userinfomap. Get (sname ); }
Public static void main (string ARGs []) { Mytest atest = new mytest ();
Userinfo auserinfo = new userinfo ("Wang xiao'er ");
Atest. setuserinfo ("head of children's group", auserinfo ); Atest. setuserinfo ("Three Shift Leaders", auserinfo );
Userinfo head of children's group = atest. getuserinfo ("head of children's group ");
If (null! = Head of the children's group) { System. Out. println (head of children's group. getname ()); } Else { System. Out. println ("children's group leader not found "); }
Userinfo Wang xiao'er = atest. getuserinfo ("Wang xiao'er ");
If (null! = Wang xiao'er) { System. Out. println (Wang xiao'er. getname ()); } Else { System. Out. println ("Wang xiao'er not found "); }
} }
|
As you can see, the above Code runs as "Wang xiao'er", that is to say, the head of the children's group is Wang xiao'er, and Wang xiao'er is also Wang xiao'er, which is normal.
Now let's comment out the first sentence in setuserinfo:
Public void setuserinfo (string sname, userinfo ainfo) { // Userinfomap. Put (sname, ainfo );
Userinfomap. Put (ainfo. getname (), ainfo ); } |
Run the above Code again and we find that the children's group leader does not exist, but Wang xiao'er is still there. we can also see that if we find "Three class leaders", we will certainly not be able to find them. That is to say, we can only find Wang xiao'er Based on Wang xiao'er's real name. Other methods won't work.
From the above analysis of setuserinfo and getuserinfo, if the modified code is used, the behavior of our program may be inconsistent, which is confusing. We set it for a long time, it's not annoying to find it!
Of course, the above Code is relatively simple, and behavior consistency can be achieved through simple modifications. However, in actual programming, behavior inconsistency is often caused by complicated behavior operations, this puzzles developers.