第20条:为私有方法名加前缀

  本条要点:(作者总结)

  • 给私有方法的名称加上前缀,这样可以很容易地将其同公共方法区分开。
  • 不要单用一个下划线做私有方法的前缀,因为这样做法是预留给苹果公司用的。

  一个类所做的事情通常都要比从外面看到的更多。编写类的实现代码时,经常要写一些只在内部使用的方法。笔者建议,应该为这种方法的名称加上某些前缀,这有助于调试,因为据此很容易就能把公共方法和私有方法区别开。

  为私有方法名加前缀还有个原因,就是便于修改方法名或方法签名。对于公共方法来说,修改其名称或签名之前要三思,因为类的公共 API 不便随意改动。如果改了,那么使用这个类的所有开发者都必须更新其代码才行。而对于内部方法来说,若要修改其名称或签名,则只需要同时修改本类内部的相关代码即可,不会影响到面向外界的那些 API。用前缀把私有方法标出来,这样很容易就能看出哪些方法可以随意修改,哪些不应轻易改动。

  具体使用何种前缀可根据个人喜好来定,其中最好包含下划线与字母p。笔者喜欢用 p_ 作为前缀,p 表示 “private”(私有的),而下划线则可以把这个字母和真正的方法名区隔开。下划线后面的部分按照常用的驼峰法来命名即可,其首字母要小写。例如,包含私有方法的 EOCObject 类可以这样写:

 1 #import <Foundation/Foundation.h>
 2
 3 @interface EOCObject : NSObject
 4
 5 - (void)publicMethod;
 6
 7 @end
 8
 9 #import "EOCObject.h"
10
11 @implementation EOCObject
12
13 - (void)publicMethod {
14     /* ... */
15 }
16
17 - (void)p_privateMethod {
18     /* ... */
19 }
20
21 @end

  与公共方法不同,私有方法不出现在接口定义中。有时可能要在 “class-continuation 分类”里声明私有方法,然而最近修订的编译器已经不要求在使用方法前必须先行声明了。所以说,私有方法一般只在实现的时候声明。

  如果写过 C++ 或 Java 代码,你可能就会问了:为什么要这样做呢?直接把方法声明成私有的不就好了吗?Objective-C 语言没有办法将方法标为私有。每个对象都可以响应任意消息,而且可在运行期检视某个对象所能直接响应的消息。根据给定的消息查出其对应的方法,这一工作要在运行期才能完成,所以 Objective-C 中没有那种约束方法调用的机制用以限定谁能调用此方法、能在哪个对象上调用此方法以及何时能调用此方法。开发者会在命名惯例中体现出 “私有方法”等语义。新手也许不适应这一点,但是必须用心领悟 Objective-C 语言这种强大的动态特性。想掌握其动态特性,确实得花大功夫,不过培养良好的命名习惯也是一条成功之道。

  苹果公司喜欢单用一个下划线作为私有方法的前缀。你或许也想照着苹果公司的办法只拿一个下划线作前缀,这样做可能会惹来大麻烦:如果从苹果公司提供的某个类中继承了一个子类,那么你在子类里可能会无意间覆写了父类的同名方法。鉴于此,苹果公司在文档中说,开发者不应该单用一个下划线做前缀。不能将方法限定于某个范围内,这也许是 Objective-C 的缺点,然而作为 “动态方法派发系统”(dynamic method dispatch system)这个强大组件的一部分,此特性也带来了诸多好处。

  你或许觉得刚才提到的那种情况不太常见,其实未必。例如,要在 iOS 应用程序中创建一个视图控制器,就得编写 UIViewController 的子类。自定义的视图控制器里可能保存着许多状态消息。你可能想编写一个方法,当视图出现在屏幕上时,可经由此方法把控制器里的所有状态都重置一遍。于是,该方法的实现代码也许会写成这样:

 1 #import <UIKit/UIKit.h>
 2
 3 @interface EOCViewController : UIViewController
 4
 5 @end
 6
 7
 8 #import "EOCViewController.h"
 9
10 @interface EOCViewController ()
11
12 @end
13
14 @implementation EOCViewController
15
16 - (void)_resetViewController {
17     // Reset state and views
18
19 }
20
21 - (void)viewDidLoad {
22     [super viewDidLoad];
23     // Do any additional setup after loading the view.
24 }
25
26 - (void)didReceiveMemoryWarning {
27     [super didReceiveMemoryWarning];
28     // Dispose of any resources that can be recreated.
29 }
30
31 /*
32 #pragma mark - Navigation
33
34 // In a storyboard-based application, you will often want to do a little preparation before navigation
35 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
36     // Get the new view controller using [segue destinationViewController].
37     // Pass the selected object to the new view controller.
38 }
39 */
40
41 @end

  可问题是,UIViewController 类本身其实已经实现了一个名叫 _resetViewController 的方法了!如果这样写的话,那么所有调用都将执行子类中的这个方法,本来该调用超类方法的地方现在调用的却是 EOCViewController 中覆写过的这个版本。由于超类中的同名方法并未对外公布,所以除非深入研究这个库,否则你根本不会察觉到自己在无意间覆写了这个方法。这毕竟是个用下划线开头的私有方法,所以没有对外公布也是合理的。由于超类方法永远不可能执行,所以这个视图控制器的行为会很奇怪,到时你可能会纳闷:为什么子类的这个方法调用得这个频繁呢,按道理不应该执行这么多次呀?

  总之,在确定使用了前缀的情况下,如果子类所继承的那个类既不在苹果公司的框架中,也不在你自己的项目中,而是来自别的框架,那么除非该框架在文档中明示,否则你无法知道其私有方法所加的前缀是什么。此时可以把自己一贯使用的类名前缀用作子类私有方法的前缀,这样能有效避免重名问题。同时还应该考虑到其他人会如何从你所写的类中继承子类,这也是私有方法应该加前缀的原因。除非使用一些相当复杂的工具,否则,在没有源代码的情况下,无法知道某个类在其公共接口之外还 定义并实现了哪些方法。

  END

  

  

  

时间: 2024-10-12 16:21:28

第20条:为私有方法名加前缀的相关文章

第20条:为私有方法名加前缀

私有方法名加上某些前缀, 1.有助于调试: 2.很容易区分公共方法和私有方法(即:容易区分哪些方法容易改动,哪些不易轻易改动.). Objective-C语言没办法将方法标为私有. 每个对象都可以响应任意消息(参见12条),而且可在运行期检视某个对象所能直接响应的消息(参见14条).根据给定的消息查出其对应的方法,这一工作要在运行期才能完成(参见11条)(Objective-C语言的动态性,动态方法派发系统(dynamic method dispatch system)). "p_"为

MyEclipse方法名加注释

Windows-->preferences-->java-->Code Style-->Code Templates-->Comments-->点击Methods-->Edit /** * @author ${user} * @create ${date} * * ${tags} */ 把上边的代码粘贴在如下图所示的红色框内-->OK-->Apply即可.

“取出数据表中第10条到第20条记录”的sql语句+select top 使用方法

1.首先.select top使用方法: 參考问题  select top n * from和select * from的差别 select * from table --  取全部数据.返回无序集合 select top n * from table  -- 依据表内数据存储顺序取前n条,返回无序集合 select * from table order by id desc -- 取全部数据.按id逆序返回有序列表 select top n * from table order by id d

Python3基础 类的伪私有属性 __加变量名 的示例

镇场诗: 诚听如来语,顿舍世间名与利.愿做地藏徒,广演是经阎浮提. 愿尽吾所学,成就一良心博客.愿诸后来人,重现智慧清净体.------------------------------------------ex1: code: class MyClass : #属性,公有的 height=10 weight=20 #伪私有属性 __haha=30; test=MyClass() print(test.__haha) result: ============= RESTART: C:\Users

PHP 的 返回引用(方法名前加&) 和 局部静态变量(static)

先阅读手册==========从函数返回一个引用,必须在函数声明和指派返回值给一个变量时都使用引用操作符 & : 例子 17-13. 由函数返回一个引用 <?php   function &returns_reference()   {       $someref = 0;       return $someref;   }      $newref = &returns_reference();//相当于 $newref = &$someref;   ?>

MySQL性能优化的最佳20+条经验

http://www.pythonclub.org/mysql/optimize-20-tips 今天,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显.关于数据库的性能,这并不只是DBA才需要担心的事,而这更是我们程序员需要去关注的事情.当我们去设计数据库表结构,对操作数据库时(尤其是查表时的SQL语句),我们都需要注意数据操作的性能.这里,我们不会讲过多的SQL语句的优化,而只是针对MySQL这一Web应用最多的数据库.希望下面的这些优化技巧对你有用. 1. 为查询缓存

系统管理员应该知道的 20 条 Linux 命令

如果您的应用程序不工作,或者您希望在寻找更多信息,这 20 个命令将派上用场. 在这个全新的工具和多样化的开发环境井喷的大环境下,任何开发者和工程师都有必要学习一些基本的系统管理命令.特定的命令和工具包可帮助开发者组织.排查故障并优化他们的应用程序,而且当出现错误时,也可以为运维人员和系统管理员提供有价值的分类信息. 无论你是新手开发者还是希望管理自己的应用程序,下面 20 条基本的系统管理命令都可以帮助您更好地了解您的应用程序.它们还可以帮助解决为什么应用程序可在本地正常工作但不能在远程主机上

【转账】MySQL性能优化的最佳20+条经验

今天,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显.关于数据库的性能,这并不只是DBA才需要担心的事,而这更是我们程序员需要去关注的事情.当我们去设计数据库表结构,对操作数据库时(尤其是查表时的SQL语句),我们都需要注意数据操作的性能.这里,我们不会讲过多的SQL语句的优化,而只是针对MySQL这一Web应用最多的数据库.希望下面的这些优化技巧对你有用. 1. 为查询缓存优化你的查询 大多数的MySQL服务器都开启了查询缓存.这是提高性最有效的方法之一,而且这是被My

Spring AOP根据JdbcTemplate方法名动态设置数据源

说明:现在的场景是,采用数据库(Mysql)复制(binlog)的方式在两台不同服务器部署并配置主从(Master-Slave)关系: 并需要程序上的数据操作方法来访问不同的数据库,比如,update方法访问主数据库服务器,query方法访问从数据库服务器. 即把"增删改"和"查"分开访问两台服务器,当然两台服务器的数据库同步事先已经配置好. 然而程序是早已完成的使用Spring JdbcTemplate的架构,如何在不修改任何源代码的情况下达到<本文标题&g