2

I am a scala developer new to swift. In scala we can share implementation across a variety of classes by "extending" a trait that has default implementations for the methods. I would like to see how to do that in swift. Here is my shot at it.

Let's consider an Alerting mechanism to be added to many application classes

protocol Alerting {
    func sendWarning(_ msg: String)
    func sendAlert(_ msg: String)
}

extension Alerting {
    func phoneHome(_ msg: String) { print(msg) }
    func sendWarning(_ msg: String) { phoneHome("WARN: \(msg)") }
    func sendAlert(_ msg: String)  { phoneHome("ALERT: \(msg)") }
}

Now let's add that Alerting to a couple of App classes:

class MyAppClass : Alerting {
    func myFunc(somethingHappened: Bool) {
        if (somethingHappened) { sendWarning("Something happened in MyAppClass.myFunc") } 
    }
}

class AnotherAppClass : Alerting {
    func anotherFunc(somethingHappened: Bool) {
        if (somethingHappened) { sendAlert("Something _bad_ happened in AnotherClass.anotherFunc") } 
    }
}

Is this a common pattern /idiom in Swift? Is there a different / more preferred approach, and why is it preferred?

Objectives for the approach:

  • Horizontally - focused functionality can be shared across disparate application classes. Think aspect oriented programming.
  • The functionality can be implemented in one place yet overridden in classes inheriting the behavior as needed
  • The behaviors are mix-ins ie they can be combined with other behaviors and do not require a rigid inheritance hierarchy

Taking a look at how my attempted implementation meets those objectives:

  • Alerting was added to two App classes that have no inherent relationship
  • The extension provides default implementations of the required behavior
  • Other unrelated protocol/extension could be added without restrictions: they meet the mix-ins goal

But I would note that my approach comes from a scala centered world and may not reflect what swift folks would prefer.

Robert Harvey
  • 198,589
  • 55
  • 464
  • 673
  • "Common" and "preferred" aren't particularly useful words in software development, unless you can provide some context. What about this approach makes it "preferred?" What sort of criteria or conditions would make some other approach more "preferred?" – Robert Harvey May 15 '20 at 22:39
  • There is some meaning to them - language specific. I'll add an example to try to clarify a bit. – WestCoastProjects May 15 '20 at 23:14
  • That's nice, but you merely restated your original premise. Your only clarification is that "preferred" can depend on the language, but you still haven't explained *why.* – Robert Harvey May 15 '20 at 23:18
  • I am intentionally leaving it a bit vague because even the reasons for the preference vary across languages. Pythonistas strongly prefer `for comprehensions` to `map`/`filter`/`reduce` for reasons I may not always agree with - but I am asking what seasoned swift developers might prefer - irrespective of _my_ particular goals. – WestCoastProjects May 15 '20 at 23:20
  • That question can't be meaningfully answered. Seasoned swift developers makes these decisions based on their experience, the information they have at hand, and the specific requirements they are being asked to fulfill. – Robert Harvey May 15 '20 at 23:21
  • Popularity only comes into play *after* all of those things are considered, and only as a tie-breaker. – Robert Harvey May 15 '20 at 23:22
  • On [Software Recommendations](https://softwarerecs.stackexchange.com/help/on-topic), they avoid this problem by requiring that all questions contain a *purpose* and a *minimal set of features.* Then, at least the community can be assured that the asker has thought a little about *what they want to accomplish.* – Robert Harvey May 15 '20 at 23:24
  • Popularity often comes in _first_ - the `for comprehensions` in python are a case in point. The above code is working well for me but I am coming from a different language. – WestCoastProjects May 15 '20 at 23:25
  • There is still a *why.* Python even has a manifesto that explains why. – Robert Harvey May 15 '20 at 23:25
  • Alright I'll see what else I can add here. – WestCoastProjects May 15 '20 at 23:26
  • Excellent. Does your approach meet all of those objectives? – Robert Harvey May 15 '20 at 23:29
  • My approach meets the objectives - but wanted input as to whether that approach were considered swift-ish or whether there were other approaches more commonly used. I do not know any other way to phrase that. – WestCoastProjects May 15 '20 at 23:31
  • Intermediate Swift dev here: this works, but you gotta be careful about bloating objects too much. It pollutes the object's method list, which makes auto-completion worse. I would make an `Alerter` class, and make `MyAppClass` and `AnotherAppClass` just use an instance of that class to do their work – Alexander Jun 04 '20 at 01:42

0 Answers0