5
3
1.概要
データの操作を行うクラスに、例えばcsvやjson形式のファイルに対する入出力を行うメソッドを実装するべきなのか悩んでいます。
ほかの有名なパッケージではデータをファイルに保存するメソッドはクラス内で実装されています。
一方ソフトウェア工学に基づけばファイルに保存するメソッドはクラス外に実装するべきだと思われます。
どちらの実装も可能です。
将来的なクラスの改変を想定されるときどちらの実装が望ましいでしょうか?
2.背景、状況
私は仕事の効率化のために個人的に少しばかりPythonを触っているものです。
検索や並び替えなど簡単なデータの操作を行うクラスを実装しようと考えています。
現時点ではファイルからデータを読み取ることをほとんど前提としています。
想定している前提状況
- クラス外からファイルに保存するのに必要なデータを完全に復元できるだけの情報にアクセスできる
- ただしクラス外から得られるデータはそのままでは適切にファイルに保存できず、保存に際してクラス内での実装に依存した処理が必要になる
- 例えばクラス初期化に際して与えたlist[float]の数列がクラス外からアクセスするとnumpy.ndarrayとして得られるなど
問題は上記の前提状況でクラス外とクラス内どちらにファイルに保存するメソッドを実装するべきかというものです。
3.調査したこと
3.1ほかのパッケージでの実装
pandasやほかの自分が利用しているパッケージを3つほど思いつく限り参考にしてみたところ、すべて入力する処理は独立した関数として分割されていますが、出力はインスタンスメソッドとして実装されていました
python
1# pandasの場合 2# ファイルからの読み込み(クラスとは独立した関数) 3dataframe : pandas.DataFrame = pandas.read_csv("data.csv") 4# ファイルへの出力(インスタンスメソッド) 5dataframe.to_csv("data.csv") 6 7# sqliteの場合 8# dbへの接続(クラスとは独立した関数) 9conn : sqlite3.Connection = sqlite3.connect("data.db") 10# dbへの書き込み(インスタンスメソッド) 11conn.commit()
3.2ソフトウェア工学的な原則
自分は最近になってSOLID原則などを知るようになった程度なので以下の考えはきちんと理解できていない人間のものだと思います。
SOLID原則における単一責任の原則に基づけば、考えているクラスはデータの改変や操作に集中するべきで、データの保存に関しては分割するべきであるように思われます。
一方でデータの操作に付随してファイルの入出力はほとんど必要な作業であるので、凝集度を上げるために一つにまとめるべきなのか判断できません。
凝集度を勘違いしていました。凝集度の視点では操作と保存が分割することは欠点にはならないと理解しました。
参考1でもデータを取り扱うクラスと保存するクラスで分割しているようです。
参考 :
4.自分なりの考え
ファイルからインスタンスを作成する際(入力時)にはクラスのインターフェースに従って入力すればよいので分割するのは簡単ですが、出力する側も分割する場合はクラスの内部につよく依存した形に実装されるように思われます。
例えば数列をクラスの中ではNumpy.ndarrayで保存していた場合、これらをjson形式で保存する関数は数列の部分をlist形式にキャストして保存する必要があります。これはクラス外の実装がクラス内の実装に強く依存しており結合度の高い実装になってしまうように思われます。
したがって自分が実装するならクラスの内部にファイルの入出力にかかわるメソッドを実装します。
先に述べた通り、自分は最近になってSOLID原則などを知るようになった者で上記の自分の考えが正しいのか全く自身がありません。
周りには質問できるようなひとがいないためこちらで質問させていただきます。皆さんのご意見を伺いたいです。
将来的なクラスの改変も予想されるときに
- クラス外にファイルへの入出力のメソッドを実装する
- クラス内にファイルへの入出力のメソッドを実装する
どちらがより理想的で望ましい実装方法でしょうか?
よろしくお願いいたします。
6.最後に
またteratailでの質問はこれが初めてなので質問場所が適切でなかった場合や、タグ付けが正しくないなどあるかもしれません。
その際はご指摘の上、ご容赦頂ければ幸いです。
回答11件
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。