How to name a method? This simple question can trigger a heat discussion and contention. As the old Bell Lab saying goes: "library design is language design", the name of method plays a vital role in the API design, and the quality of method naming distinguishes DSL-like design from unreadable ones.
The Java Way
In Java, we were educated to use a verb + noun to name a method. With the knowledge of design patterns, we really have a bunch of verbs to select, createXxx or makeXxx for factory, buildXxx for builder, just to name some. This naming scheme makes it clear that it's a method, or more casually, an action, which "does something".
But is this kind of naming scheme unquestionable?
In one recent Java project, we need to create lots of stub data to mock the response from web services for unit testing. In one unit test, the code is just like this:
java 代码
- AbstractResponse<AResponseType> response =
- new AbstractResponse<AResponseType>(createStubAResponseType());
And in method createStubAResponseType, code goes like this:
java 代码
- AResponseType response = new AResponseType();
-
- resposne.setPartOne(createStubPartOne());
- resposne.setPartTwo(createStubPartTwo());
- resposne.setPartThree(createStubPartThree());
-
- return response;
Pretty straightforward. But the problem with me is that they read NOT so naturally. Why the prefix "create" for every stub data creation method?
Wouldn't
java 代码
- new AbstractResponse<AResponseType>(stubAResponseType());
and
java 代码
- resposne.setPartOne(stubPartOne());
- resposne.setPartTwo(stubPartTwo());
- resposne.setPartThree(stubPartThree());
be better?
It's a small step, but I think it makes difference. For the reason, read on.
The Ruby Way
For Ruby newbies, it takes quite a while to get used to the method naming convention used in Ruby (and especially Rails). Initially, it appears confusing to tell what is a field, what is a method, or what on earth it is (this definitely occurred to me)!
E.g., here's a dummy Rails generator excerpted from book Rails Recipe:
ruby 代码
- class TumblepostGenerator < Rails::Generator::NamedBase
- def manifest
- record do |m|
- m.class_collisions class_name
- m.template "app/controllers/controller_template.rb" ,
- "app/controllers/#{file_name}_controller.rb"
- m.template "app/models/model_template.rb" ,
- "app/models/#{file_name}.rb"
- m.directory File.join('app/views' , file_name)
- m.template "app/views/form_template.rhtml" ,
- "app/views/#{file_name}/_form.rhtml"
- m.template "app/views/view_template.rhtml" ,
- "app/views/#{file_name}/_view.rhtml"
- m.readme "POST_GENERATION_REMINDER"
- end
- end
- end
Notice how methods are named:
- class_collisions instead of check_class_collisions
- class_name instead of get_class_name
- directory instead of make_directory
- readme instead of set_readme (or set_readme_file)
- And the most beautiful one: record (a protected method defined in Rails::Generator::Base) instead of create_record or new_record.
If you take a look at class Generator::Base, you will find all methods are named this way:
manifest instead of define_manifest, usage_message instead of show_usag_message, etc.
In Ruby, methods are named after the return value, using a noun.
Compared with the scheme used in Java, this means we don't care about whether it's an action we need to carry out or it's already there, we just "read" it out.
Ruby's method naming convention is more result-oriented and, from Bertrand Meyer's (the author of Object-Oriented Software Construction) point of view, more object-oriented, cause it treats method and field in unified way. And this is one of the reasons why Ruby is so suitable for define internal DSL (the other reasons are closure/iterator, hash, etc.).