Ccmmutty logo
Commutty IT
6 min read

宣言型UIのリファクタリング

https://cdn.magicode.io/media/notebox/blob_Qbr7KCt

概要

宣言型UIは書きやすい反面、夢中で書いていくとどんどんネストして何がどの部分なのかどこの描写なのかわかりづらくなってしまいがちです。なので今回はメソッドや変数などを使い、可読性の高いコードを実現します。
参考としてSwiftUIで記述したコードを載せます。難しいことはやっていないのでSwiftUIができなくても読めると思います。
ちなみにVStackは縦、HStackは横にviewを配置していくものです。

対象読者

これから宣言型UIを使う方
読みづらさを感じている方
例えば以下のようなセルを一覧表示したい時
このようなコードになります。

リファクタリング前

var body: some View {
        List {
            ForEach(0..<10) {_ in
                VStack {
                    HStack {
                        Rectangle()
                            .frame(width: 50, height: 50)
                            .foregroundColor(.red)

                        VStack(alignment: .leading) {
                            Text("テキスト")
                            Text("テキスト")
                                .foregroundColor(.gray)
                                .font(.system(size: 12))
                            Text("テキスト")
                                .foregroundColor(.gray)
                                .font(.system(size: 8))
                        }
                        Spacer()
                        VStack {
                            Spacer()
                            HStack {
                                Button(action: {

                                }, label: {
                                    Rectangle()
                                        .frame(width: 15, height: 15)
                                        .foregroundColor(.blue)
                                })
                                Button(action: {

                                }, label: {
                                    Rectangle()
                                        .frame(width: 15, height: 15)
                                        .foregroundColor(.blue)
                                })
                            }
                        }
                    }
                }
            }
        }
    }
このコードには幾つか問題があります。 まず一つ、コードとviewでそれぞれどれがどこに該当するかが一見してわかりづらいです。修正を加えたい時、どこをいじればいいかを探すのに時間が取られてしまいます。
それからもう一つあげるなら、VStack、HStackの括弧の始まりと終わりがわかりづらいですね。これはIDEによっては気にならないことかもしれませんが、XCodeだとなるべくひとめでわかるようにしておきたいところです。
より読みやすくリファクタリングしてみたコードがこちらです。

リファクタリング後

var body: some View {
        List {
            ForEach(0..<10) {_ in
                VStack {
                    HStack {
                        image()

                        description()

                        Spacer()

                        buttonView()
                    }
                }
            }
        }
    }

    private func image() -> some View {
        return Rectangle()
            .frame(width: 50, height: 50)
            .foregroundColor(.red)
    }

    private func description() -> some View {
        return VStack(alignment: .leading) {
            Text("テキスト")
            Text("テキスト")
                .foregroundColor(.gray)
                .font(.system(size: 12))
            Text("テキスト")
                .foregroundColor(.gray)
                .font(.system(size: 8))
        }
    }

    private func buttonView() -> some View {
        return VStack {
            Spacer()
            HStack {
                button {
                }

                button {
                }
            }
        }
    }

    private func button(action: @escaping () -> Void) -> some View {
        return Button(action: {
            action()
        }, label: {
            Rectangle()
                .frame(width: 15, height: 15)
                .foregroundColor(.blue)
        })
    }
だいぶスッキリしましたね。メソッドの定義がある分、元のコードより長くなってしまっていますが、それぞれの始まりと終わりが瞬時にわかるようになりました。
一つ注意点がありまして、body内は同じ粒度で記述しないと急に可読性が落ちます。どういうことかというと、
.
.
.
Rectangle()
            .frame(width: 50, height: 50)
            .foregroundColor(.red)

description()
.
.
.
とするとメソッドの方を見落としやすくなってしまうので、サイズ感はある程度整えたほうが良いです。

おまけ

Refactor -> Extract to Method でメソッド化出来ます。まれに戻り値がsome Viewではなくなりエラーが出るかもしれませんが、その場合はsome Viewに変えれば問題ありません。 Android Studioでも同じような機能があるので、Flutterでも出来ます。

Discussion

コメントにはログインが必要です。