【问题标题】:Information Hiding the "Swifter" way?信息隐藏“更快”的方式?
【发布时间】:2023-03-18 23:06:01
【问题描述】:

我有一个关于面向对象设计原则和 Swift 的问题。我对 Java 非常熟悉,我目前正在参加 udacity 课程,以便在 Swift 中获得第一手经验。

在 Java 社区中(基本上在每个遵循 OOP 的社区中),使用信息隐藏技术(例如在类中隐藏或封装数据)非常常见,以确保不会从外部对其进行操作。一个共同的原则是将类的所有属性声明为私有,并使用 getter 来检索属性的值,并使用 setter 来进行操作。

我在编写作为课程一部分的课程时尝试采用这种方法,它看起来像这样:

//
//  RecordedAudio.swift
//  Pitch Perfect
//

import Foundation

class RecordedAudio: NSObject {
    private let filePathUrl: NSURL!
    private let title: String?

    init(filePathUrl: NSURL, title: String?)
    {
        self.filePathUrl = filePathUrl
        self.title = title
    }

    func getFilePathUrl() -> NSURL
    {
        return filePathUrl
    }

    func getTitle() -> String
    {
        if title != nil
        {
            return title!
        }
        else
        {
            return "none"
        }
    }
}

代码有效,我的私有属性无法从我的类外部访问,这正是我想要实现的行为。但是,我想到了以下问题:

1.) 课程讲师决定将属性的访问控制级别保留为默认的“内部”,并且不使用 getter/setter,而是直接从外部访问属性。关于为什么开发人员可能会迅速这样做的任何想法?我的方法不够“迅速”吗???

2.) 总之:在编写自己的类时,是否有一种“更快”的方式来实现封装?什么是 swift 的原生技术来实现我的目标信息隐藏?

【问题讨论】:

  • 感谢您将这些问题与我联系起来。然而,他们都认为 Swift 缺少访问修饰符,而在当前版本中并没有。 Swift 确实有访问修饰符并且它们可以工作,这是个好消息 :-) 但是,我想知道 Apple 希望我们如何在 OOP 和信息隐藏方面使用它们!这就是我的问题所在:-)
  • 早期版本的 swift 缺少访问修饰符,这就是为什么在这个问题上仍然存在一些混淆的原因。在这种情况下,您主要对限制对属性设置器的访问感兴趣,@akashivskyy 的方法似乎是普遍接受的答案。

标签: oop swift information-hiding


【解决方案1】:

您可以通过将属性public 标记为读取并将private 标记为写入来限制外部属性操作,如in the documentation 所述:

class RecordedAudio: NSObject {

    public private(set) let filePathUrl: NSURL!
    public private(set) let title: String?

    init(filePathUrl: NSURL, title: String?) {
        self.filePathUrl = filePathUrl
        self.title = title
    }

}

// in another file

let audio = RecordedAudio(filePathUrl: myUrl, title: myTitle)

let url = audio.filePathUrl // works, returns the url
audio.filePathUrl = newUrl // doesn't compile

【讨论】:

  • 我喜欢这样。看起来“很快”:-) +1 让我们看看是否还有其他建议加入,否则我会将其标记为答案!
【解决方案2】:

我这样做有点像在 Obj-C 中:

class MyClass
  private var _something:Int
  var something:Int {
    get {return _something}
// optional: set { _something = newValue }
  }
  init() { _something = 99 }
}

...
let c = MyClass()
let v = c.something

上面是一个原始示例,但处理得非常严格,它是一个很好的模式。

【讨论】:

  • 我也试过了。但是,在这种情况下,如何从外部访问 getter?
  • getter 是这样公开的。只需使用let v = <class>.something
猜你喜欢
  • 2021-02-13
  • 1970-01-01
  • 1970-01-01
  • 2019-03-06
  • 1970-01-01
  • 1970-01-01
  • 2012-02-05
  • 2014-05-05
  • 1970-01-01
相关资源
最近更新 更多