accagg開発日記: クラス分けとCSV形式での保存

開発しているとリポジトリ名とか何かとプロジェクトに名前が必要になるので、Account Aggregator を縮めて accagg と名付けました。

前回まででとりあえず三井住友銀行の取引明細を取得することができたので、データを正規化してCSV形式に保存することを考えます。セキュリティを考えると平文のCSV形式なんて論外なのですが、そこは後々実装します。試す場合は個人の責任でお願いします。

前回は main にすべての処理を書いていたので、今後のことを考えてクラス分けしてみます。作ってみたクラス図は以下です。

正直クラス図が合ってるかわかりません(汗 なんとなくやりたいことが伝わればいいかな。

スクレイピングする処理は銀行ごとに異なるため、abstract.Aggregator という抽象クラスを作って、それを継承した smbc.Aggregator で三井住友銀行用の処理を実装するようにしてみました。将来的には Factory パターン? Factory Methodパターン? みたいなもので、どの銀行用の Aggregator でも統一された方法でインスタンスを生成するようにできるといいなと思ってます。(デザインパターンも勉強中・・)

もう1つ、PassBookクラスを作りました。明細のデータを保存するクラスです。今の所は CSV 形式で保存する実装にしますが、将来的にはセキュアな実装にしようと思います。PassBookは 1 種類の口座の明細を記録します。例えば、普通預金と定期預金のように別の種類の明細は、それぞれPassBookを持つイメージです。なので 1 つの銀行口座に対して複数のPassBookが関連します。本当はこの辺も多重度などを使ってクラス図で表せると良いのですけどね。ドメインモデルも作ればこの辺スッキリするのかなぁ。

最初は Aggregator が PassBook に直接データを渡すような構成を考えていたのですが、Aggregator はユーザが自由に作成できるようにするつもりなので、悪意のある Aggregator が PassBook のデータを抜き出せないように、間に main を挟んで直接の関係しない形にしました。Aggregator はネットアクセスしても怪しまれないクラスなので、余計なデータにアクセスできないほうが良さそうだからです。

PassBookItem はクラスの形をしていますが、Python の dictionary で実装します。Pythonの dictionary をクラス図で表すにはどうすればいいんでしょうか・・。

ちなみに Aggregator の run() 関数の戻り値は

{
  'ordinary': #普通預金
  [
    {'date': datetime.date(2018,8,20), 'deposit': 1234, 'balance': 1234, 'desc': '入金'},
    {'date': datetime.date(2018,8,28), 'deposit': -1234, 'balance': 0, 'desc': '払い戻し'},
  ]
  'time-deposit': #定期預金
  [
    {'date': datetime.date(2018,8,20), 'deposit': 1234, 'balance': 1234, 'desc': '入金'},
    {'date': datetime.date(2018,8,28), 'deposit': -1234, 'balance': 0, 'desc': '払い戻し'},  
  ]
}

のような形式を考えていて、1行1行が PassBookItem を意味してるつもりです。これはクラス図上どう表したらいいものか・・。PassBookItemの配列を持つ PassBookItemList を作って、その配列を返すべきか?

こんな感じ? でも、これだと同じ name を持つ PassBookItemList も許容してしまうし。どうするんだろう。

ひとまずクラス図の正当性は置いておいて、作成したコードを置いておきます。クラス分けしてパッケージも作ってファイルが増えてきたのでアーカイブしました。そのうち github にリポジトリを置いて公開したいけど、まだまだそんなレベルではないので、とりあえずここで公開します。

実行ファイルは main.py から accagg.py に名前を変更しました。相変わらず ID とパスワードは直書きなので書き換えてください。うまく動作すれば、SMBC-ordinary.csv というファイルが作られるはずです。

コメントする

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です