2017年の記事。
enumを使って分析用のイベントを表現するケースが記事だと出てくる。IDだけなら良いけど、メタデータとか、他にも付与したい情報が出てくるが、structで表現するともっと改善できるよ。と書いてある。
extension AnalyticsEvent { var name: String { switch self { case .loginScreenViewed, .loginAttempted, .loginSucceeded, .messageListViewed: return String(describing: self) case .loginFailed: return "loginFailed" case .messageSelected: return "messageSelected" case .messageDeleted: return "messageDeleted" } } var metadata: [String : String] { … } }
enumは何かを網羅するのには便利だと思うけど、分析用のイベントは別に網羅したいわけではない。
今回の例だとstructはイベントごとに個別に定義して、情報を受け取るためのprotocolを用意するのかと思っていた。けれども、イベントを表現するstructを作り、initメソッドを隠蔽する代わりに、structを得るためのメソッドやプロパティを生やしているという感じだった。
struct AnalyticsEvent { var name: String var metadata: [String : String] private init(name: String, metadata: [String: String] = [:]) { self.name = name self.metadata = metadata } static func loginFailed(reason: LoginFailureReason) -> AnalyticsEvent { return AnalyticsEvent( name: "loginFailed" metadata: ["reason" : String(describing: reason)] ) } static let loginSucceeded = AnalyticsEvent(name: "loginSucceeded") … }
方式はなんでもいいと思うんだけど、この形式にすると分析ログを送信する際にどういう情報が必要なのかが明らかになって良いなと思う。
ここ一年くらい品質やテストについて考えながら仕事をしている中で、値の網羅性を担保するというのはめちゃめちゃ大事だなと思って網羅という言葉がキーワードになりつつある。
追記
この記事に対するレスポンスでDave Delongという人が別の提案をしている記事を見つけた。protocol使えばよくて、enumでも、structでもなんでも好きにできるよと。