文档章节

为什么要使用getter和setter / accessor?

 技术盛宴
发布于 2019/12/07 20:45
字数 1841
阅读 24
收藏 0

使用仅获取和设置的getter和setter而不是仅对这些变量使用公共字段的优点是什么?

如果getter和setter所做的不只是简单的get / set,我可以很快地弄清楚这一点,但是我不清楚如何做到这一点:

public String foo;

比以下任何方面都更糟糕:

private String foo;
public void setFoo(String foo) { this.foo = foo; }
public String getFoo() { return foo; }

而前者需要更少的样板代码。


#1楼

从面向对象的设计角度来看,这两种选择都可能通过削弱类的封装来破坏代码的维护。 对于讨论,您可以看一下这篇出色的文章: http : //typicalprogrammer.com/?p=23


#2楼

除非当前交付需要,否则不要使用getters setter,例如,对于大多数生产应用程序,系统中的更改请求,如果有什么要更改的内容,请不要考虑太多。

简单,轻松地思考,并在需要时增加复杂性。

我不会利用深奥的技术知识的企业主的无知,因为我认为这是正确的,或者我喜欢这种方法。

我编写了庞大的系统,而没有使用访问修饰符和一些方法来验证n执行biz逻辑的getters setter。 如果您绝对需要。 使用任何东西。


#3楼

好吧,我只是想补充一点,即使有时它们对于变量/对象的封装和安全性是必需的,如果我们想编写一个真正的面向对象程序,那么我们就需要停止过度使用这些访问者 ,因为有时我们依赖很多何时不需要它们,这几乎与我们将变量公开一样。


#4楼

一个公共领域并不比没有返回或分配给它做任何事情的getter / setter对更糟糕。 首先,很明显(在大多数语言中)没有功能上的区别。 任何差异都必须在其他因素上,例如可维护性或可读性。

并非经常提到吸气剂/设置剂对的优点。 有人声称您可以更改实现,而不必重新编译客户。 据说,setter可以让您稍后添加诸如验证之类的功能,而您的客户甚至不需要了解它。 但是,向验证器添加验证是对其先决条件的更改,这是对先前合同的违反 ,这很简单,就是“您可以在此处放置任何东西,以后可以从获取器中获得相同的东西”。

因此,既然您违反了合同,那么就应该而不是避免更改代码库中的每个文件。 如果您避免这种情况,您将假设所有代码都假定这些方法的约定是不同的。

如果这不应该是合同,则该接口允许客户端将对象置于无效状态。 这与封装完全相反。如果从一开始就无法将该字段真正设置为任何值,那么为什么从一开始就不进行验证?

同样的论点也适用于这些传递性getter / setter对的其他假定优点:如果您以后决定更改所设置的值,则您正在违反合同。 如果您以某种无害的修改(例如日志记录或其他不可观察的行为)的方式覆盖了派生类中的默认功能,则您正在破坏基类的契约。 这违反了《里斯科夫可替代性原则》,后者被视为面向对象的宗旨之一。

如果一个类的每个字段都具有这些愚蠢的获取器和设置器,那么该类就没有任何不变式,也没有合同 。 那真的是面向对象的设计吗? 如果所有的课程都是那些getter和setter,那只是一个哑数据持有人,而哑数据持有人应该看起来像哑数据持有人:

class Foo {
public:
    int DaysLeft;
    int ContestantNumber;
};

在此类中添加传递式获取/设置对不会增加任何价值。 其他类应该提供有意义的操作,而不仅仅是字段已经提供的操作。 这样便可以定义和维护有用的不变量。

客户 :“我可以用这个类的对象做什么?”
设计器 :“您可以读写几个变量。”
客户 :“哦,太酷了,我猜是吗?”

有使用getter和setter的理由,但如果不存在这些理由,以假封装之神的名义创建getter / setter对并不是一件好事。 进行getter或setter的有效理由包括经常提到的事情,这些事情是您以后可以进行的潜在更改,例如验证或不同的内部表示形式。 或者,该值应该对客户端可读,但不可写(例如,读取字典的大小),因此,简单的getter方法是不错的选择。 但是,当您做出选择时,这些原因应该存在,而不仅仅是您以后可能想要的潜在原因。 这是YAGNI的一个实例( 您将不需要它 )。


#5楼

Getter和setter方法是访问器方法,这意味着它们通常是更改私有类成员的公共接口。 您可以使用getter和setter方法定义属性。 即使在类中将getter和setter方法定义为方法,也可以将它们作为属性访问。 类之外的那些属性可以具有与类中的属性名称不同的名称。

使用getter和setter方法有一些优点,例如使您能够创建具有可以像属性一样访问的复杂功能的成员的能力。 它们还允许您创建只读和只写属性。

尽管getter和setter方法很有用,但您仍应注意不要过度使用它们,因为,除其他问题外,它们还会使代码维护在某些情况下更加困难。 此外,它们还提供对您的类实现的访问,例如公共成员。 OOP实践不鼓励直接访问类中的属性。

在编写类时,总是鼓励您尽可能多地将实例变量设为私有,并相应地添加getter和setter方法。 这是因为有时您可能不想让用户更改类中的某些变量。 例如,如果您有一个私有的静态方法来跟踪为特定类创建的实例数,则您不希望用户使用代码来修改该计数器。 每当调用该变量时,只有构造函数语句应使该变量递增。 在这种情况下,您可能会创建一个私有实例变量,并只允许将getter方法用于计数器变量,这意味着用户只能使用getter方法来检索当前值,而他们将无法设置新值使用setter方法。 创建不带setter的getter是使类中的某些变量为只读的简单方法。

本文转载自:https://stackoom.com/question/6Zvn/为什么要使用getter和setter-accessor

粉丝 0
博文 1201
码字总数 0
作品 0
深圳
高级程序员
私信 提问
加载中

评论(0)

Javascript 不可不知的秘密 -- Class 与 面向对象

1.类对象的创建方式 new 关键字,通过调用 constructor()方法来创建对象 Object.create(), es5 2. 类的属性 属性特性 可写(writable) : 可以设置,修改属性的数值 可枚举(enumerable) : 可以...

longjuelegend
2016/09/06
37
0
[C/C++]属性的秘密——C++仿C#的属性实作

一直以来,我都想为C++引入C#里面定义的属性(Property),我尝试了几次: [C/C++]一个实现反射和事件绑定的例子 [C/C++]一个实现反射和事件绑定的例子 (增强版) [C/C++]模仿C#实作C++版属性...

梁欢
2013/11/10
1.1K
0
iOS:属性、修饰词(内存管理) 及其对应成员变量 、ARC

------------早期GCC版本------------ --@property A作用就是让编译器在h文件声明A 的setter/getter方法; --@synthesize A作用就是让编译器在m文件生成A 的setter/getter方法;(如果自己实现...

北方人在上海
2016/01/11
74
0
[Core Java® for the Impatient]重载Java2

Chapter 2. Object-Oriented Programming Set(Mutator Methods)方法改变对象的状态,Get(accessor methods)方法则不; Java中变量不持有对象,他们引用对象; 变量的实例和方法的实现在类...

小紅
2016/04/20
42
0
Objective-C 之 @property和@synthesize

我用了不到一周的时间学习了Objective-C,后面的大部分时间我都在了解如何使用IOS的SDK和一些高级的话题,到目前已经有两个多月的时间了。目前能做一些简单的应用,但是在写代码的时候明显感...

XMAN2017
2013/04/29
1.3W
11

没有更多内容

加载失败,请刷新页面

加载更多

UGUI图片层级和渲染顺序的奇怪关系

之前见别人的文章总是说,在Hierachy下,相同图集的图片要连续排列,这样Unity会对相同图集的图片进行合批,从而减少draw call。今天做了简单的试验发现情况并不是这么简单的。 第一种情况:...

myctrd
45分钟前
48
0
jQuery中$.each()方法的使用-Json对象-dom元素

对于循环我们首先会想到for循环,但是在前端对数组我们可以使用,但是对于json对象,想把对象中的属性的key-value循环去取出,那么for循环提供不了的。而each方法则给我们提供了便利,下面介...

imzchloe
55分钟前
59
0
Linuxprobe第六天

待补充

nt狮子男人
55分钟前
58
0
gem install:无法构建gem native扩展(找不到头文件)

我正在使用Fedora 14,我安装并运行了MySQL和MySQL服务器5.1.42。 现在我尝试以root用户身份执行此操作: gem install mysql 但我得到这个错误: Building native extensions. This could ...

技术盛宴
今天
51
0
就8张图片带你搞清楚JS的原型链

JS(JavaScript)是目前互联网开发中十分重要的一门编程语言,他承载着网页、手机应用程序、硬件程序、微信、微信小程序中的各种特效及处理逻辑功能。

涂老师
今天
52
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部