封装:我不认为这意味着您认为的含义

我关于不变性的帖子激起了轰动,并在reddit和此处引起了很多评论,从令人生畏的到有趣的。

评论类型

它们可以或多或少地分为以下几类:

  • 我们什么也不要考虑,也不要犹豫不决-除了“可怕”之外没有有效的论点
  • 一个线程想知道代码审查的目的,捕获错误或共享知识
  • 我很乐意在以后的文章中讨论的理性反驳
  • “它破坏了封装!” 这是我想在这篇文章中解决的问题。

封装,真的吗?

我已经写过关于封装的文章,但是如果木头很硬,我想敲几次钉子是很自然的。

年轻的时候,当我学习OOP时 ,就被告知了它的特点:

  1. 遗产
  2. 多态性
  3. 封装形式

这是在维基百科上找到的定义

封装用于指两个相关但截然不同的概念之一,有时还指其组合:

  • 一种语言机制,用于限制直接访问对象的某些组件。
  • 一种语言构造,它有助于将数据与对数据进行操作的方法(或其他功能)捆绑在一起。
—维基百科

简而言之,封装意味着不能直接访问对象的状态,而只能通过其方法。 在Java中,它直接转换为具有私有属性和公共访问器(即getter和setter)的JavaBeans约定 。 这是当前困扰我们的悲伤状态,许多人在谈论封装时都提到了这种状态。

对于这种模式根本没有封装! 不相信我吗? 检查以下代码段:

publicclassPerson{

    privateDatebirthdate=newDate();

    publicDategetBirthdate(){
        returnbirthdate;
    }
}

鉴于没有设置方法,因此不可能在Person实例中更改日期。 但它是:

Personperson=newPerson();
Datedate=person.getBirthdate();
date.setTime(0L);

哎哟! 毕竟,国家没有那么好被封装...

一切都归结为一个很小的区别:我们希望访问生日的值,但我们很高兴将引用返回到保存该值的birthdate字段。 让我们对其进行更改,以将值本身与引用分开:

publicclassPerson{

    privateDatebirthdate=newDate();

    publicDategetBirthdate(){
        returnnewDate(birthdate.getTime());
    }
}

通过创建一个与原始引用不共享任何内容的新Date实例,可以实现真正的封装。 现在可以安全地调用getBirthdate()

请注意,本质上是不可变的类 -在Java中,原语, String以及像这样开发的类,完全可以安全共享。 因此,完全public那些类型的字段而忽略吸气剂是完全可以接受的。

还要注意, 例如在构造函数中注入引用会带来完全相同的问题,应以相同的方式进行处理。

publicclassPerson{

    privateDatebirthdate;

    publicPerson(Datebirthdate){
        this.birthdate=newDate(birthdate.getTime());
    }

    publicDategetBirthdate(){
        returnnewDate(birthdate.getTime());
    }
}

问题是,大多数虔诚地调用封装的人都乐于与外界分享他们的领域参考。

结论

这里有两个结论:

  • 如果您具有可变字段,则简单的getter(例如由IDE生成的那些)将提供封装。
  • 只有返回可变字段,而不返回字段本身,才能使用可变字段实现真正的封装。
  • 一旦有了不可变的字段,就可以通过getter访问它们让字段final完全相同。

注意:如果您了解上述模因参考,则对您表示敬意

翻译自: https://blog.frankel.ch/encapsulation-dont-think-means-think-means/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值