Money Forward Developers Blog

株式会社マネーフォワード公式開発者向けブログです。技術や開発手法、イベント登壇などを発信します。サービスに関するご質問は、各サービス窓口までご連絡ください。

20230215130734

Atomic Design を導入してみた話

こんにちは。 iOSエンジニアの廣瀬です。

以前から感じていた課題に、デザインデータ・UIコンポーネントの管理 がありました。 その解決策として Atomic Design の考え方を取り入れてみました。

今日は、"(しら)ずにお金が(たま)る"自動貯金アプリ『しらたま』( https://sirata.ma/ )の開発時に実施した Atomic Designの導入 について紹介します。

デザインデータ・UIコンポーネントの管理

ここでいう デザインデータ・UIコンポーネント とはデザイナーが使っているツール(Sketch)や、フロントエンドとなるiOSアプリのコードレベル(Swift)の話です。 具体的に管理がうまくいっていない状態とは下記のような状態と言えます。

  • カラーコードやフォント名がコミュニケーションを取るときに飛び交う
  • アプリ全体で フォント の使い方にコンセプトが無い
  • Sketchとプログラムコードのどちらが正しいかわからない
  • 新しいメンバーが入ってきたとき等にデザインのコンセプトを説明できるものが無い

新しい UI が増えるたびにアプリで使われる フォント も増えることは好ましく無いです。なぜなら誰かに問われるたびに毎回誰かが調べる必要があるからです。

またUI が増えるたびに上記のようなことをしていればSketch もしくは Swift で変更があるたびに該当箇所を 都度 アップデートする必要があります。 このような状況が続くとSketchSwift の間で不整合が出ることもあります。 時には忘れるし、時にはミスもします。 だって、にんげんだもの。 そうなると、どっちがマスターか判らなくなります。

そして、マスターも正しく無い。 デザインに対するコンセプトも決まっていないので新しいメンバーへの説明・現状を伝えるコストもかかってきます。

このような課題を感じていたときに Atomic Design というデザイン設計手法を知り、この問題も解決してくれると思い導入することにしました。

Atomic Design

Atomic Designの詳細はここでは割愛します。 参考リンクをいくつか載せておきます。

上の記事でも述べられているものもあるのですが Atomic Designによって先に挙げた課題の解決が期待できます。

UIComponentに名前がついている

これは課題に挙げていた

カラーコードやフォント名がコミュニケーションを取るときに飛び交う アプリ全体で フォント の使い方にコンセプトが無い

の改善につながります。

ただ名前をつけるだけではなく、用途ごとやその UIComponent が表したいことを考え名前付けすることで意味が明確になります。 名前づけができるということはプログラムコードにも落としやすく共通化が測りやすいです。 またカラーコードを伝え合うよりもこの名前を伝え合うことで認識のズレをなくす事にもつながります。

デザインデータが管理しやすい

デザインデータが管理しやすくなるのも Atomic Design の特長と言えるでしょう。 結局はAtomsの組み合わせで画面を構成していくので、極論を言うと Atoms の定義さえ共有すれば、画面を構成することができるようになります。 そして、全体の フォント の種類は決定されていて、変更もしやすくなっています。 primary と名前づけられた色を変更したい場合も Sketch であっても Swift であっても変更箇所が1箇所ずつなのでデータがずれてしまう可能性も減ります。

つまり

  • Sketchとプログラムコードのどちらが正しいかわからない
  • 新しいメンバーが入ってきたとき等にデザインのコンセプトを説明できるものが無い

の改善につながる事になります。

導入ハードル

Atomic Design を導入する上でいくつかハードルがありました。 一番大きなものが Atomic DesignUIComponent の命名をどうしていこうか、それに関連してデザイナーがこういった抽象化しつつ意味のある名前づけをする事に慣れていない点でした。

このハードルをまず超えて、かつ中途半端なものにしてしまえば Atomic Design が崩壊してしまいます。

そこで私たちの以下のステップを踏んで UIComponent の定義を行なっていきました。

  1. まず大味にいつも通りに画面のデザインを組む。だが、将来的には UIComponent 化するので統一性を考えてデザイン・コーディングする。この時でも一応命名は適当にしておく。
  2. 大体のアプリの全体構成が見えてきたところで命名を考えて、Swiftのコードを書き換える
  3. デザイナーに命名したもの・その意図を共有。あとは統一できるものはしたりして調整
  4. デザイナーの SketchLibraries を使って定義を移行していく

というステップを踏んでUIComponent を定義していきました。 注目すべきはエンジニアが名前づけ等を行なっているところです。 普段から名前大事を意識しているので、エンジニアが考えたほうが早く、そしていい名前づけができるだろうと思ってこのアプローチを取りました。

あとは SketchLibraries を活用してデザインツール側の効率化にも成功したと感じています。

実際に導入してみて

実際に導入してみての感想は「導入してとてもよかった」です。 修正も自信を持ってでき、コードレベルにおいても宣言的に書きやすく使いやすい感じになりました。 少し嬉しい誤算だったのが名前づけ通りの構造にする事でデザイナーも Swift で書かれているUIComponent の内容をコードを読んで理解できた点でした。この記事 にも書いてあるのですが、エンジニアが命名したUIComponentSketchに反映させる作業もデザイナーがSwiftファイルに書かれている内容を読み取ることができたので比較的に楽に移行ができたと考えています。

可読性大事。簡単な部分であればデザイナーに修正してもらいたい考えを持っているチームであっても Atomic Design を導入することは役に立つかもしれません。

最後にイメージしやすいように一例として実際にしらたまで使われている Color の定義と Font の定義を載せます。

public enum Color: Int, Enumerable {
    case ukon
    case midori
    case syojyohi
    ...
    
    
    public var color: UIColor {
        switch self {
        case .ukon:
            return UIColor(red: 239 / 255, green: 187 / 255, blue: 36 / 255, alpha: 1)
        case .midori:
            return UIColor(red: 34 / 255, green: 125 / 255, blue: 81 / 255, alpha: 1)
        case .syojyohi:
            return UIColor(red: 232 / 255, green: 48 / 255, blue: 21 / 255, alpha: 1)
            ...
        }
    }
public struct Font {
    let size: FontSize
    let name: FontName
    
    public var font: UIFont {
        return UIFont(name: name.rawValue, size: size.rawValue)!
    }
    
    public init(size: FontSize, name: FontName) {
        self.size = size
        self.name = name
    }
    
}

public enum FontSize: CGFloat {
    case xHuge = 42
    case huge = 30
    case xLarge = 24
    case large = 20
    ...
}

public enum FontName: String {
    case enRegular = "AvenirNext-Regular"
    case enMedium = "AvenirNext-Medium"
    ...
}

public enum FontType: Int, Enumerable {
    case largeTitleBold
    case title
    case titleBold
    case link
    case doneBold
    case assisting
    case assistingBold
    ...
    
    public var font: UIFont {
        switch self {
        case .largeTitleBold:
            return Font(size: .large, name: .jaBold).font
        case .title:
            return Font(size: .medium, name: .jaRegular).font
        case .titleBold:
            return Font(size: .medium, name: .jaBold).font
        case .link:
            return Font(size: .small, name: .jaRegular).font
        case .doneBold:
            return Font(size: .small, name: .jaBold).font
        case .assisting:
            return Font(size: .small, name: .jaRegular).font
        case .assistingBold:
            return Font(size: .small, name: .jaBold).font
    ...
        }
    }
}

最後に

マネーフォワードでは、課題を改善につなげ、効率化を探求するエンジニアを募集しています。 ご応募お待ちしています。

【採用サイト】 ■マネーフォワード採用サイトWantedly | マネーフォワード

【マネーフォワードのプロダクト】 自動家計簿・資産管理サービス『マネーフォワード』 ■WebiPhone,iPadAndroid

「しら」ずにお金が「たま」る 人生を楽しむ貯金アプリ『しらたま』 ■WebiPhone,iPad

ビジネス向けクラウドサービス『MFクラウドシリーズ』 ■バックオフィス業務を効率化『MFクラウド』会計ソフト『MFクラウド会計』確定申告ソフト『MFクラウド確定申告』請求書管理ソフト『MFクラウド請求書』給与計算ソフト『MFクラウド給与』経費精算ソフト『MFクラウド経費』入金消込ソフト『MFクラウド消込』マイナンバー管理ソフト『MFクラウドマイナンバー』資金調達サービス『MFクラウドファイナンス』

メディア ■くらしの経済メディア『MONEY PLUS』