【外文翻译】 为什么我要写 getters 和setters
原文作者: Shamik Mitra
原文链接:https://dzone.com/articles/why-should-i-write-getters-and-setters
当我开始我的java职业生涯的时候,我就对getters 和setters感到疑惑。有一个问题经常在我脑海里冒出来:为什我要写getters和seters。这种语法对我来说是很奇怪的。
我知道如果用public来修饰的话,类中的变量可以被所有包(packages)访问到,getters/setters 方法也是这样。我也在做相同的事情——用private修饰变量,同时用public修饰其对应的getters 和setters方法,这样就可以在所有包中访问了。
所以下面两种写法有什么不同呢?
public String name = "Shamik";
// caller:
String name = X.name; //(X is a object instance);
X.name = "Shamik Mitra";
private String name = "Shamik";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// caller:
String name = X.getname();
X.setName("Shamik Mitra");
后来我慢慢意识到为什我们要使用getters/setters,还有为何他们如此重要。在这篇文章中,我会分享一些相关的感悟。
感悟
“用public修饰一个变量”和“通过getters/setters来操作这个变量”最主要的区别是在实质上保持变量的控制。如果你用public修饰一个变量,这以为着你可以直接访问到它,并且可以对这个变量做所有操作。例如,你可以把这个变量设为null,当你在其他方法中使用这个变量的时候,可能抛出空指针异常。
但是,如果你提供了getter/setter方法,这是一种间接的访问,它并不能完全地控制这个变量。为这个变量赋值的唯一方法就是通过setter方法,同样地只能通过getter方法来获取变量的值。所以现在你所定义的变量就只有一个“入口”和“出口”。并且,因为getter/setter是方法,这意味着里面可以写代码,你可以做校验去检查这些变量。因此,对象可以决定是否为这个变量赋值。当调用getter方法的时候,你可以决定返回一个真正的引用或者是复制它并返回。
所以 getters/setters 就像是保险丝或者是断路器。当发生什么错误的时候,保险丝就会从主电路中分离以保证电路是安全的。这里概念是一样的,如果有什么错误发生,setter可以不把值传过去。
当你看完这些解析之后,我知道你仍然有一个问题:
“你说的我知道啊,但通常,我们都不在getters/setters方法里面写其他东西。我们只是返回和设这个变量。这和直接用pulic修饰变量,把它完全暴露出去一样。所以你说这些做什么?”
对于这个问题,我说的是在写getters/setters的时候,我们创建了一个规制可以在以后加入任何的校验。现在里面是没有校验,但以后有什么问题的话,我们只需要在setter里面加入校验相关的代码就行了。
但对于这个问题现在仍然有很多争论,并且有很多人支持下面这个观点:YAGNI (You Ain't Gonna Need It——你根本就不需要它)。他们说,当这个变量没有必要去校验的时候,为什么还要这么麻烦去写getter/setter?我直接用public 把它公开得了。
按我的理解,YAGNI的主要问题是想要使代码避免不必要的复杂。这就像有些人会想得很多,他们使代码尽量地简单普通以便之后做任何修改。但大多数他们所考虑到的改变都不会来。
总结
getters/setters 不会使你的代码变得复制,并且是便于以后的校验。所以,尽管写吧。
译者注: getters/setters的概念出现已经很久了,对于有经验的程序员或许都有自己的理解。其实我们现在写getters/setters方法很多时候是受到框架的约束,无论是在数据端和前端都大量使用到javaBean,getters/setters是必不可少的。写起来也不麻烦,反正编译器可以直接生成。 但现在有写数据存储的框架已经开始舍弃getter和setter,甚至连成员变量也舍弃了,直接用一个map来保持变量名和其对应的值, 使代码变得非常的简洁。当然,这也有着明显的缺点。
【外文翻译】 为什么我要写 getters 和setters的更多相关文章
- 为什么要使用getters和setters/访问器?
Why use getters and setters/accessors? 实际上会有很多人问这个问题....尤其是它成为Coding Style中一部分的时候. 文章出自LBushkin的回答 T ...
- JavaBean的getters和setters方法自动生成
xgClass.java文件: public class XgClass { private String ccCityDerate1000Num; } 添加getter/setter方法: 在代码区 ...
- use getters and setters Learning PHP Design Patterns
w Learning PHP Design Patterns Much of what passes as OOP misuses getters and setters, and making ac ...
- Mongoose 预定义模式修饰符 Getters 与 Setters 自定义修饰符
mongoose 预定义模式修饰符 mongoose 提供的预定义模式修饰符,可以对我们增加的数据进行一些格式化,主要有:lowercase.uppercase .trim,这里不一一演示,对trim ...
- [REPRINT]Properties vs. Getters and Setters
http://www.python-course.eu/python3_properties.php Our new class means breaking the interface. The a ...
- [翻译]如何用YII写出安全的WEB应用
前言 虽然本文是基于YII1.1,但其中提到的安全措施适用于多数web项目安全场景,所以翻译此文,跟大家交流.原文地址. 目录 安全基本措施... 2 验证与过滤用户的输入信息... 2 原理... ...
- 【翻译】从头开始写一个时间序列数据库-Writing a Time Series Database from Scratch
本文来自: https://fabxc.org/tsdb/, 如翻译有误,请纠正. 我是从事监控工作的.特别是Prometheus, 一个包含自定义的时间序列库以及集成Kuberntes的监控系统. ...
- 在EntityFramework6中管理DbContext的正确方式——1考虑的关键点(外文翻译)
(译者注:使用EF开发应用程序的一个难点就在于对其DbContext的生命周期管理,你的管理策略是否能很好的支持上层服务 使用独立事务,使用嵌套事务,并行执行,异步执行等需求? Mehdi El Gu ...
- 在EntityFramework6中管理DbContext的正确方式——2DbContext的默认行为(外文翻译)
(译者注:使用EF开发应用程序的一个难点就在于对其DbContext的生命周期管理,你的管理策略是否能很好的支持上层服务 使用独立事务,使用嵌套事务,并行执行,异步执行等需求? Mehdi El Gu ...
随机推荐
- mysql 修改数据库data存放位置
一.首先把mysql的服务先停掉. 二.更改MySQL配置文件My.ini中的数据库存储主路径 打开MySQL默认的安装文件夹C:\Program Files\MySQL\MySQL Server 5 ...
- 《C++之那些年踩过的坑(二)》
C++之那些年踩过的坑(二) 作者:刘俊延(Alinshans) 本系列文章针对我在写C++代码的过程中,尤其是做自己的项目时,踩过的各种坑.以此作为给自己的警惕. 今天讲一个小点,虽然小,但如果没有 ...
- Vue学习之路---No.6(分享心得,欢迎批评指正)
我们还是先回顾一下上一次的重点: 1.事件绑定,我们可以对分别用方法和js表达式对事件进行处理 2.当方法名带括号的时候,在方法中一定要传参:而不带括号的时候,vm会自动配置默认event 3.各类事 ...
- springmvc基础学习3---注解简单理解
1:@Controller 用来注解这个bean是MVC模型中的一个C 会被spring的auto-scan扫到纳入管理.Spring mvc框架中的action层注入,也就是控制层.控制器Contr ...
- 享受release版本发布的好处的同时也应该警惕release可能给你引入一些莫名其妙的大bug
一般我们发布项目的时候通常都会采用release版本,因为release会在jit层面对我们的il代码进行了优化,比如在迭代和内存操作的性能提升方面,废话不多说, 我先用一个简单的“冒泡排序”体验下r ...
- 用 Visual Studio Code 调试 Node.js
环境: Visual Studio Code Node.js 1. 关闭运行中的程序 2.打开入口文件,我这里的入口文件为 app.js 3.点击左侧菜单栏的 debug 按钮 4.点击运行按钮 5 ...
- JS把命名空间传递给模块形式
//方法依赖 jquery 或者其他 有扩展方法 extend() 类库 例如: underscore.js 链接地址 http://underscorejs.org var app = {}; ( ...
- c#关于时间TimeHelper类的总结
using System; namespace DotNet.Utilities{ /// <summary> /// 时间类 /// 1.SecondToMinute( ...
- java实现微信红包分配算法
红包算法分析 有人认为,抢红包的额度是从0.01到剩余平均值*N(N是一个系数,决定最大的红包值)之间,比如一共发了10块钱,发了10个红包:第一个人可以拿到(0.01~1*N)之间的一个红包值,当然 ...
- React-Native 之 项目实战(三)
前言 本文有配套视频,可以酌情观看. 文中内容因各人理解不同,可能会有所偏差,欢迎朋友们联系我. 文中所有内容仅供学习交流之用,不可用于商业用途,如因此引起的相关法律法规责任,与我无关. 如文中内容对 ...