A Developer and Ramyun (Instant Noodles) Recipe
Let’s take a look at the cooking directions at the back of the ramyun bag.
(1) Boil 550ml of water and vegetable mix.
(2) Add noodles and soup base, and boil for another 4 minutes.
Number 3 is recommendations on how to eat the ramyun so we can say it’s actually 2 steps. But if you actually think about yourself cooking ramyun, you can see there are actually a lot more steps than this.
(1) Take out the pot.
(2) Add 550ml of water and vegetable mix into the pot.
(3) Heat up the pot with water and the ingredients in it.
(4) Wait for the water to boil.
(5) Once the water starts to boil, add noodles and soup base.
(6) Boil for another 4 minutes.
(7) Turn off the heat.
(8) Transfer the ramyun into a bowl.
It can be written with more detail. If you look closely, there are several omitted steps within ‘heat up the pot’. It may vary depending on equipment so branching it is necessary.
(1) If it's an induction, turn on the power and increase the temperature by pressing the button.
(2) If it's a gas stove, open the gas valve, and turn the dial to light it up.
(3) If it's a portable gas stove, shake the gas bottle, insert it, lock it in, and then light up the fire.
But no ramyun recipe includes the above directions. That’s because they consider the readers to be aware of that much detail, or the ramyun company simply doesn’t care. You may think it’s too obvious but these kinds of codes are quite common. They may do more than what’s expressed in the name of the function, or overly detailed implementations may be revealed. In these cases, there are usually many if and for statements, and the codes are lengthy.
Imagine, for example, you encountered a function called fetchRecentArticles. You can expect that the tasks performed by this function are as follows:
(1) Load the stored articles as appropriate.
(2) Select and return the ones generated within the last X days.
However, as you check inside the function, what if you are checking the local cache within the function, and if there are none, call the server API, import and parse the data, define the key values to load data from storage, and creating different filtering logic according to the types of articles using switch statements? The core part gets lost inside the lengthy codes. Even if you try to modify the code, you have to find out where to modify it for a long time. You’re explaining how to turn on the heat when you only need to know that you have to boil the water for the ramyun.
A similar meaning can be found in this video in which Richard Feynman answered the reporter’s question, “Why do magnets push each other away?” Even if the same question is asked, the explanation varies widely depending on who the interviewer is (Someone who majored in physics, an ordinary person, an alien, etc.) or what the interviewer wants to know. It could be a single-phrase answer like, “That’s just the way it is,” or it could be an explanation with endless detail.
Think about whether the code you’ve written is revealing only an appropriate level of logic. You need to examine and correct whether they are only working on a task appropriate for a function’s role, or they’re lining up all kinds of detailed logic. But there is no answer to an ‘appropriate level’. It depends on the class or module that the code belongs to. It may also vary depending on the ability of the reader/writer. A concise code may be a code that is more difficult to understand for some. If you refactor a code, the standards may change again. Everything is fluid. There is no set standard, but the readers can at least read their code once more, practice making the functions short, review the code with colleagues and adjust it to an appropriate level.
It’s not easy to adhere to the single responsibility principle that an object should have only one responsibility, but let’s start with a function unit first. If you’re now able to make a concise function, apply it at the class level next. The single responsibility principle is the beginning of all patterns or architecture. That means, if you aren’t able to adhere to the single responsibility principle, no matter what pattern you use or what architecture you bring in, there’s a high possibility that it’ll eventually become a spaghetti code as time passes. If you study language grammar as a means of concise expression, you may not get lost. Let’s practice making functions shorter and making classes smaller.
For additional reference
Revisiting Object Oriented Programming with Swift: Coding Habits to Avoid
Sourcery 개발자로부터 배우는 모바일 아키텍처와 개발자 경험
iOS 개발자라면 한번은 들어봤거나 써봤을 오픈소스 툴 Sourcery를 만든 Krzysztof Zabłocki와 팟캐스트 녹음을 했는데 작년 엉클밥을 봤을 때와 비슷한 큰 자극와 영감을 얻었습니다. Krzysztof는 좋은 앱 아키텍처와 개발자 툴을 만들어서 개발자 경험을 개선하는 것에 목표를 두고 여러 툴을 만들면서 현재 뉴욕타임스에서 iOS 팀을 리딩하고 있는 개발자입니다.
잘못된 선택보다 올바른 선택을 하는게 더 쉬운 구조가 좋은 아키텍처다.
이 분은 모바일 아키텍처와 프로그래밍을 굉장히 실용주의적인 관점으로 해석하고 실행에 옮기시는 분이란 인상을 받았습니다. 그는 좋은 아키텍처를 구분하는 기준은 그 아키텍처를 쓰는 개발자가 얼마나 행복한가로 판단해야 한다고 합니다. 또한 좋은 아키텍처란 ‘잘못된 선택보다 올바른 선택을 하는게 더 쉬운 구조’라고 합니다. 왜냐면 인간은 여러 갈래가 있을때 쉬운 길을 택하는 경향이 있기 때문이죠. 좋은 코드를 짜기 위해 아키텍처와 싸워야하는게 최악의 상황이라고 합니다.
그래서 이분이 지금까지 만든 것들을 보면 의외로 간단한 아이디어에서 시작하지만 매일 매일 프로그래밍하는 개발자들의 생산성을 증가시켜주거나, 불필요한 반복 작업을 줄여서 실수를 줄여주거나, 코드를 좀 더 좋은 구조로 짜게 강요(?)하는 마법을 부리는 것 같습니다. Protocol extension으로 앱 로깅을 담당하는 싱글턴 객체를 숨기면서 유닛테스트도 할 수 있게 해주는 방법이라던지, 유저가 버그 리포트를 했을 당시 유저의 앱의 상태를 복원할 수 있는 데이터 스냅샷 기능 등을 보면 기존 코드를 많이 뜯어고치지 않는 간단한 방식으로 팀 전체의 개발 및 디버깅 경험을 개선시켜줍니다.
애플 엔지니어들마저 베껴간 Sourcery
더 대단하고 인기 많은 툴도 있습니다. Sourcery라는 툴은 스위프트에서 Equatable이나 Codable 프로토콜 등을 쓸 때 자동으로 구현 코드를 생성해주는 툴입니다. 지금이야 스위프트 자체에서 지원하는 부분이 있지만 초창기에는 디폴트 구현를 지원하지 않아서 모든걸 다 수동으로 구현해줘야 했을때 만들었다고 합니다. 이걸 만들고 얼마 지나지 않아 애플 엔지니어들마저 내부에서 사용하기 시작했다고 합니다. 재밌게도 그걸 알게된건 애플 엔지니어들이 회사 정책 때문인지 오픈소스에 직접 PR을 보내진 못하고 트위터 비공개 DM으로 패치를 보내주면서 버그를 고쳐 달라고 요청이 들어오기 시작했다네요.
애플의 거짓말을 들춰낸 Objective-C Playground
또 하나 놀라운 일화는 애플이 WWDC에서 스위프트 플레이그라운드를 발표하면서 옵젝씨로는 이런거 못한다고 말한걸 듣고 빡쳐서 불과 12시간만에 옵젝씨 플레이그라운드를 만들어버림으로써 애플이 틀렸다는걸 증명해버렸습니다. 이 프로젝트는 옵젝씨 뿐 아니라 스위프트까지 지원하고, 애플에서 만든 스위프트 플레이그라운드와는 비교도 안되게 훨씬 빠르다고 자랑합니다. 심지어 플러터처럼 앱 hot reloading도 할 수 있게 해버렸네요. ‘Code Injection’이라는 키워드를 처음 배웠습니다.
iOS 아키텍처와 테스팅
마지막으로 이 분은 iOS 개발을 하기 전에는 게임 엔진도 만들고 그래픽 개발도 하고 웹/백엔드 개발도 해봤는데, 모바일 진영이 그 중 제일 테스트코드 짜기를 꺼려하는 분위기라고 합니다. 그 이유 중 하나는 아마도 애플이 제시하는 MVC가 테스트하기 극도로 안좋은 아키텍처이기 때문인거 같다고 하네요. 일단 테스트가 잘 되려면 UIKit과 완전히 분리된 로직만 담당하는 클래스가 있어야하는데 “애플의 MVC”는 기본적으로 injection도 없고 composition도 없어서 그게 어렵다는 의견을 제시합니다. 그럼 대체 애플은 왜 십 수년간 MVC만 미는가, 좀 더 나은 아키텍처를 밀어주는 변화는 없을까란 질문에 대해서도 꽤 그럴듯한 답변을 내놨습니다.
일단 MVC 외에 인기있는 주류 아키텍처로는(2017년 발표 당시) MVVM과 VIPER(또는 여타 unidirectional architecture)가 있는데요. 먼저 MVVM은 FRP스러운 바인딩이 있어야하는데 이건 잘 만들기도 어렵고 당장 UIKit과 잘 맞지 않아서 후보가 될 수 없고, VIPER는 어려워서 배우기 쉽지 않다고 합니다. 애플은 신규 개발자들이 애플 플랫폼에 쉽게 들어오기를 바라기 때문에 이렇게 어려운 아키텍처를 밀어줄리는 없다고 하네요. 아키텍처에 대한 폭넓은 인사이트는 몇 년 전에 했던 인기 많았던 발표를 참고하시면 되겠습니다. Good iOS Application Architecture: MVVM vs. MVC vs. VIPER. 2020년 현재, Combine과 SwiftUI가 생겼으니 MVC를 벗어나기 쉬워졌을까요?
바로 오늘 도움이 되는 실용적인 코드와 툴을 만들어내는 개발자
이분은 프리랜싱과 컨설팅을 한 적이 있어서 그런지 개발 생산성과 코드 재사용성을 끌어올리는 아키텍처와 tooling에 전문가셨고, 특히 본인이 필요해서 만든 툴로 인해서 얼마를 벌었다는걸 구체적인 액수로 말하는게 정말 인상적이었습니다. 왜냐면 프리랜서는 시간이 수입으로 직결되니까 툴을 만들어서 매일 반복 작업으로 쓰이던 시간을 줄이거나 예전 프로젝트에서 썼던 코드를 재활용할 수 있게 되면 그게 곧바로 수입으로 계산될 수 있기 때문이겠죠. 엉클밥이나 GoF 옹들이 이론과 이상향을 제시하는 분들이라면 Krzysztof는 그 이론과 디자인 패턴을 바탕으로 당장 오늘 도움이 되는 실용적인 코드와 툴을 만들어내는 개발자 같았습니다. 특히, 매일 해야하는 디버깅과 코딩에서 최대한 반복 작업을 없애고 좋은 아키텍처가 퍼질 수 있게 꾸준히 무언가를 만들고 고민하는 모습에서 정말 큰 영감을 얻을 수 있었습니다.
Tags: mobile architecture, developer experience, Krzysztof Zabłocki
Learn Mobile Architecture and Development Experience from a Sourcery Developer
I recorded a podcast with Krzysztof Zablocki, who created Sourcery, which is an open-source tool that an iOS developer may have heard about. I was greatly inspired just like last year I’ve seen him. Krzysztof is a developer who leads the iOS team in New York Times and has a goal that aims to improve the developer experience by creating good app architecture and developer tools.
Good architecture is a structure where it’s easier to make the right choice than the wrong one.
I got the impression that he is a person who interprets mobile architecture and programming from a very pragmatic perspective and puts it into practice. He says the standard for distinguishing a good architecture should be judged on how happy the developer who uses it is. Also, he says good architecture is a structure where it’s easier to make the right choice than the wrong one. Because humans tend to choose the easy path when they have multiple choices. The worst thing is to fight the architecture to create a good code.
So if you look at what he’s created until now, it starts from an unexpectedly simple idea, but increases the productivity of developers who program every day, reduce unnecessary repetition to reduce mistakes, or magically force(?) codes to be made with a better structure. His work improves the whole team’s development and debugging experience through a simple method that does not modify existing codes as much as possible if you look at features like data snapshots and others which can recover the app’s status when the user sent a bug report. or the method where you can hide the singleton object which is in charge of app logging using the protocol extension and carrying out unit testing.
Sourcery that Even Apple Engineers Copied
There are better and more popular tools. Sourcery is a tool that automatically generates implementation codes when using protocols such as Equatable or Codable in Swift. There are parts that are supported in Swift itself now, but the default implementation was not initially supported, so it was created when everything had to be manually implemented. Not long after making this, even Apple engineers started using it internally. Funny thing is, they found out about this because the Apple engineers could not send PRs directly to the open source because of the company policy so they had to use Twitter’s private DMs to send patches and request for bug fixes.
Objective-C Playground Revealed Apple’s Lies
Another surprising story is that when Apple announced Swift Playgrounds in WWDC, they said that Objective-C cannot do something like this. In just 12 hours, Objective-C Playground was created and Apple was proven wrong. This project not only supports Objective-C, but also Swift, and it’s much faster than Apple’s Swift Playground beyond comparison. It’s even possible to do hot reloading like Flutter. I learned the keyword ‘Code Injection’ for the first time.
iOS Architecture and Testing
Lastly, before he became an iOS developer, he used to make game engines, develop graphics, and do web/back-end development. He says among them the mobile part is the most reluctant to write test codes. One of the reasons is that MVC provided by Apple is an extremely bad architecture for testing. For testing to work well, there needs to be a class that is in charge of logic that is completely separated from UIKit, but “Apple’s MVC” doesn’t even have an injection and composition so the opinion is that it’s difficult. Then why does Apple use MVC for more than 10 years? There’s a pretty good answer to the question asking whether there would be any changes that would push for a better architecture.
First, mainstream architectures other than MVC(based on the 2017 announcement), there are MVVM and VIPER(or other unidirectional architecture). MVVM needs to have an FRP-like binding, but this is difficult to make and not very compatible with UIKit right away, so it cannot be a candidate, and VIPER isn’t easy to learn. Apple wants new developers to enter the Apple platform easily, so there’s no way they would push difficult architectures like this. For a broad insight into architecture, you can refer to the popular announcement made a few years ago. Good iOS Application Architecture: MVVM vs. MVC vs. VIPER. Now in 2020, since we now have Combine and SwiftUI, is it easier to get out of MVC?
A Developer Who Creates a Practical Code and Tools That Can Help You Today
Since he has experience in freelancing and consulting, he’s an expert in architecture and tooling which increases development productivity and code reusability. Also, it was especially impressive that he mentioned the specific amount of money he earned from the tools he created out of need. Since time directly relates to income for freelancers, if you create a tool to reduce time spent on redundant tasks every day, or codes used in a previous project become reusable, they will count as income right away. If Uncle Bob and GoF were people who show theory and ideals, Krzysztof is like a developer who creates practical codes and tools that will help you today based on that theory and design patterns. I was especially inspired by the way he thought and constantly created something to spread good architecture and get rid of redundant tasks in debugging and coding as much as possible.
Tags: mobile architecture, developer experience, Krzysztof Zabłocki