1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

メソッドチェーンとは

オブジェクトに対して複数のメソッドを連続して呼び出すテクニックです。
メソッドチェーンを活用することで中間の一時変数を削減でき、コードの可読性を向上させることができます。

メソッドチェーンがよく使用される例として、DjangoのORMやPandasなどのライブラリが挙げられます。

メソッドチェーンで書く場合と、一時変数を用いる場合の例

通常の書き方(一時変数を使用する場合)

result = obj.method1()
result = result.method2()
result = result.method3()

メソッドチェーンを使用する場合以下のように書けます。

result = obj.method1().method2().method3()

メソッドチェーンを使える条件

メソッドチェーンを実現するには、各メソッドが戻り値として自分自身(self)または同じ型のオブジェクトを返すように実装する必要があります。

簡単な例: メソッドチェーン対応クラス

class Example:
    def __init__(self, value):
        self.value = value

    def add(self, num):
        self.value += num
        return self  # 自分自身を返す

    def multiply(self, num):
        self.value *= num
        return self  # 自分自身を返す

    def result(self):
        return self.value

# メソッドチェーンの利用
example = Example(10)
final_value = example.add(5).multiply(2).result()
print(final_value)
# 出力結果: 30

add()multiply() メソッドは、自分自身 (self) を返すため、連続して呼び出すことができます。

実際に作成してみる

ここでは、PostgreSQLにSQLクエリを発行するためのクエリビルダーを実装します。

初めにメソッドチェーンを意識せずに作成した場合と、メソッドチェーンを意識して作成した場合を比較します。

メソッドチェーンなしのクエリビルダー

class QueryBuilder:
    def __init__(self):
        self._query = ""

    def select(self, *columns):
        cols = ", ".join(columns) if columns else "*"
        self._query += f"SELECT {cols} "

    def from_table(self, table_name):
        self._query += f"FROM {table_name} "

    def where(self, condition):
        self._query += f"WHERE {condition} "

    def order_by(self, column, desc=False):
        direction = "DESC" if desc else "ASC"
        self._query += f"ORDER BY {column} {direction} "

    def build(self):
        return self._query.strip() + ";"

qb = QueryBuilder()
qb.select("id", "name", "age")
qb.from_table("users")
qb.where("age > 18")
qb.order_by("name")
query = qb.build()

print(query)

# 出力結果:
# SELECT id, name, age FROM users WHERE age > 18 ORDER BY name ASC;

この場合、各メソッドがselfを返さないため、個別の呼び出しが必要です。
コードの行数が増え、中間状態のオブジェクトが残りやすくなります。

メソッドチェーンありのクエリビルダー

次に、メソッドチェーンに対応したバージョンです。

class QueryBuilder:
    def __init__(self):
        self._query = ""

    def select(self, *columns):
        cols = ", ".join(columns) if columns else "*"
        self._query += f"SELECT {cols} "
        return self

    def from_table(self, table_name):
        self._query += f"FROM {table_name} "
        return self

    def where(self, condition):
        self._query += f"WHERE {condition} "
        return self

    def order_by(self, column, desc=False):
        direction = "DESC" if desc else "ASC"
        self._query += f"ORDER BY {column} {direction} "
        return self

    def build(self):
        return self._query.strip() + ";"


# クエリビルダーを使ってクエリを構築
query = (QueryBuilder()
         .select("id", "name", "age")
         .from_table("users")
         .where("age > 18")
         .order_by("name")
         .build())

print(query)
# 出力結果:
# SELECT id, name, age FROM users WHERE age > 18 ORDER BY name ASC;

まとめ

メソッドチェーンを意識することでよりシンプルで可読性が高いコードを書くことができます。
ぜひメソッドチェーンを活用してみてください!

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?