13
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ElixirAdvent Calendar 2023

Day 23

【Elixir アンチパターン】 tuple、maps、structを使おう

Last updated at Posted at 2023-12-22

引き続き、Elixir アンチパターンを読んでみます。

今日は、primitive-obsessionです。

住所を処理するプログラムで、住所を文字列型に入れておいて、郵便番号や国名などを必要に応じて取得したり、書き換えたりする例です。

defmodule MyApp do
  def extract_postal_code(address) when is_binary(address) do
    # Extract postal code with address...
  end

  def fill_in_country(address) when is_binary(address) do
    # Fill in missing country...
  end
end

住所の文字列データをそのまま使うのはアンチパターン。構造化されたデータで保存してそれを扱うのがよいという話でした。
お勧めの例では、Addressというstructを作って:street, :city, :state, :postal_code, :countryを入れるようにしています。

defmodule Address do
  defstruct [:street, :city, :state, :postal_code, :country]
end
defmodule MyApp do
  def parse(address) when is_binary(address) do
    # Returns %Address{}
  end

  def extract_postal_code(%Address{} = address) do
    # Extract postal code with address...
  end

  def fill_in_country(%Address{} = address) do
    # Fill in missing country...
  end
end

この住所の例は、文字列だと扱いずらいので、さすがに、パースして構造化したデータで保存しますよね。
そもそも、構造化した状態で入力してもらうだろう。
まあ、これは例なので、特殊な想定ですが、実際には、文字列のまま最初の1文字目がXXXで、2文字目以降が
YYYなどと決まりを作って、文字列のまま処理するとかありそう。
map,tuple,structを適切に使いましょう。

mapとstructはほぼ同じですが、structは、

  • あらかじめ指定したキーしか使えない。
  • 指定したキーは必ず存在する。
    という違いがあります。

structは、moduleを作って宣言しないといけないので、ちょっと面倒なんですが、キーがなにか明確なので、好んで私は、好んで使ってます。
以前、Axonのソースコードを読んだらStruct効率的に使われていて、読んでみて使い方の勉強になりました。

どんなプログラミング言語でも同じだと思いますが、処理対象のデータを適切なデータ型に保存して取り扱う事は大事ですね。

以前、次の記事で、defstructを使った記事をかいてるので、興味ある方はどうぞ。

13
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?