質の高いコードを書くことは、継続的な改善プロセスです。
練習を続ければ、誰でも何年もかけて上達していきます。あなたが今日書いたコードは、おそらく2年前に書いたコードよりも良いだろうし、おそらく1年後に書くコードよりも悪くなるでしょう。それもプロセスの一部なのだから。
だから、もしあなたが常にコードの品質を向上させたいと思っているなら、ここにあなたの旅に役立つ小さなヒントをいくつか紹介しましょう。
1. エクステンション・パターンを使ってコードの塊をグループ化する
セットアップコードをあるエクステンションにまとめ、デリゲートを別のエクステンションにまとめるといった具合です。将来的には、読みやすく、メンテナンスしやすくなります。
// MARK: - Setup
extension HomeViewModel {
func configureInitialState() { ... }
func fetchCards() { ... }
}
// MARK: - Actions
extension HomeViewModel {
func search(text: String) { ... }
func addCard(_ card: Card) { ... }
}
2. ファイルあたりの最大行数を決める
そしてそれを守ること。その行数を超えたら、ファイルを2つ以上のファイルに分割する。前に見た拡張子パターンを使うこともできます。
3. 説明的な名前の変数と関数を作る
あなたのコードにとって最良のドキュメントは、自動ドキュメント化されたコードです。このコンセプトの基本は、説明的な名前をつけることです。さらに、できる限りパラメータ・プレースホルダを使いましょう。
var result = 3
// Not the same as:
let numberOfSessions = 3
func update(id: Int, amount: Int) { .. }
// Not the same as:
func updateBalance(toUser userID: Int, with amount: Int) { .. }
4. typealias を活用する
typealias を使うことで、コードにセマンティクスを加えることができます。こうすることで、誰かが初めてあなたのコードを見たときに、理解しやすくなります。
typealias ApiHeaders = [String:String]
func getHeaders() -> ApiHeaders {
var headers = ApiHeaders()
headers["x-api-token"] = "asf232asgf5"
headers["content"] = "application/json"
return headers
}
5. "ノー・ハッピー・パス "に気をつけよう
エラーが起きたらどうしますか?ユーザーに知らせていますか?アクションを再試行する可能性を与えていますか?私たちは常にハッピーパスを優先し、その後のエラー処理を忘れがちです。
// Avoid this approach
do {
// Perform some task
...
} catch {
print(error)
}
------
struct SinginView: View {
@State private var showingAlert = false
@State private var alertMessage = ""
var body: some View {
VStack {
.....
Button("Sign In") { tryToSignin() }
}
.alert("Error", isPresented: $showingAlert, actions:
Button("Ok") {}
}, message: {
Text(alertMessage)
})
}
}
extension ContetnView {
func tryToSignin() {
do {
// Perform some task
...
} catch {
showingAlert = true
alertMessage = error.localizedDescription
}
}
}
6. 強制アンラップとインデックスの見直し
nil オブジェクトの強制アンラップとアウトオブバウンド・インデックスは、最も一般的なクラッシュ原因の1つです。ほんの2、3行余分に書くだけで簡単に回避できます。
let intString = ... // some value you get from a server
let int = Int(intString)
// Avoid
print(int!)
// Go safe with if-let
if let int = Int(intString) {
print(int)
}
let array = [.....] // Bunch of elements
// Add an extra safety net to access the values
extension Array {
public subscript(safeIndex index: Int) -> Iterator.Element? {
return index >= 0 && index < endIndex ? self[index] : nil
}
}
let numbers = [10, 23, 12, 63, 1, 3]
let number1 = numbers[safeIndex: 0] // = 10
let number2 = numbers[safeIndex: 6] // = nil
7. 機密情報はどのように扱っていますか?
パスワードをサーバーに送信する前にハッシュ化していますか? API キーのような機密情報をキーチェーンに保存していますか?
簡単に使えるラッパーが欲しければ、私の Keychain の記事を参照してほしい。
8. コードの重複を避ける
同じコードを2回書く必要があるなら、リファクタリングの指標となります。もし3回目を書く必要があるなら、それは必ずやらなければならないことです。
9. コードに直接メッセージをハードコーディングするのは避ける
全てのメッセージを一元管理するマネージャーを持つか、直接ローカライズするのがベストだと、私は長年にわたって発見してきました。こうすることで、1つのメッセージを何度も使う場合、メンテナンスが簡単になります。
enum UserMessages {
case loginSuccess
case loginError(_ error: String)
func getMessage(withKey key: String = "") -> String {
switch self {
case .success:
return NSLocalizedString("Success!", comment: key)
case .error:
return NSLocalizedString("An error occurred. Please try again later.", comment: key)
}
}
}
10. あらかじめ組み込まれている機能を活用する
Foundation フレームワークにすでに含まれている機能を利用しましょう。以下はその例です。
var bool = false
bool.toggle() // bool = true
struct Person {
let name: String
let age: Int
}
var array = [Person(name: "John", age: 30), Person(name: "Jane", age: 20), Person(name: "Mike", age: 20)]
print(array.map({ $0.name })) // ["John", "Jane", "Mike"]
print(array.filter({ $0.age == 30 })) // [{"John", 30}]
array.forEach{print($0.name)} // "John" "Jane" "Mike"
コード品質を向上させるために使っているヒントが他にありますか? コメントで教えてください。
何か質問がありますか? お気軽にメッセージをお寄せください。私のコンテンツが気に入ったら、私の Medium ページを購読してください。
もし私をサポートしたいなら、 GitHub か Twitter でフォローしてください。
【翻訳元の記事】
10 quick tips to increase your iOS code quality
https://medium.com/@blorenzop/code-quality-tips-f53a69b3f786