Movatterモバイル変換


[0]ホーム

URL:


酒と泪とRubyとRailsと

コマンド(Command) | Ruby デザインパターン


GoFのデザインパターン(Design Pattern)のコマンド(Command)のRubyコードを使った紹介記事です。
コマンドデザインパターンは、あるオブジェクトに対してコマンドを送ることでそのオブジェクトのメソッドを呼び出すことです。

たとえば、ファイルシステムの実装は知らなくてもユーザーはファイルの追加、削除といったコマンドを実行できます。これもコマンドパターンのひとつです。

🍮コマンドの構成要素

コマンドの構成要素は、シンプルに2つです。

  • Command(コマンド):コマンドのインターフェイス
  • ConcreteCommand(具体コマンド):Commandの具体的な処理

🍣コマンドのメリット

  • コマンドの変更・追加・削除に対して柔軟になる

🎳ソースコード

コマンドデザインパターンを説明するために、ファイルの作成・削除・コピーができるモデルを考えます。

  • Commandクラス:すべてのCommandのインターフェイス
  • CreateFileクラス(ConcreteCommand):ファイルを作成する
  • DeleteFileクラス(ConcreteCommand):ファイルを削除する
  • CopyFileクラス(ConcreteCommand):ファイルをコピーする
  • CompositeCommand(ConcreteCommand):複数のコマンドをまとめて実行できるようにした、CreateFile, DeleteFile, CopyFileのコマンドを集約するクラス

まず、すべてのコマンドのインタフェースを規定するCommandクラスです。
このクラスで定義した#executeメソッドと#undo_executeメソッドをCreateFile, DeleteFile, CopyFileが持っています。

# コマンドのインターフェース
classCommand
attr_reader:description
definitialize(description)
@description = description
end

defexecute
end

defundo_execute
end
end

次にCreateFileクラス,DeleteFileクラス,CopyFileクラスです。各クラスの共通した特徴は次のとおりです。

  • 各クラスはCommandクラスを継承したConcreteCommand
  • #executeメソッド:ファイル作成、ファイル削除、ファイルコピーを実装
  • #undo_executeメソッド:ファイル作成、ファイル削除、ファイルコピーを取り消す

なお、最初にrequireしているfileutilsは、ファイルを操作するためのライブラリです。

require"fileutils"

# ファイルを作成する命令
classCreateFile< Command
definitialize(path, contents)
super("Create file :#{path}")
@path = path
@contents = contents
end

defexecute
f = File.open(@path,"w")
f.write(@contents)
f.close
end

defundo_execute
File.delete(@path)
end
end

# ファイルを削除する命令
classDeleteFile< Command
definitialize(path)
super("Delete file :#{path}")
@path = path
end

defexecute
if File.exists?(@path)
@content = File.read(@path)
end
File.delete(@path)
end

defundo_execute
f = File.open(@path,"w")
f.write(@contents)
f.close
end
end

# ファイルをコピーする命令
classCopyFile< Command
definitialize(source, target)
super("Copy file :#{source} to#{target}")
@source = source
@target = target
end

defexecute
FileUtils.copy(@source, @target)
end

defundo_execute
File.delete(@target)
if(@contents)
f = File.open(@target,"w")
f.write(@contents)
f.close
end
end
end

最後にCreateFileクラス,DeleteFileクラス,CopyFileクラスを組み合わせて実行できるようにしたCompositeCommandクラスです。このクラスもCommandを継承している、ConcreteCommandのひとつです。

# 複数のコマンドをまとめて実行できるようにしたオブジェクト
classCompositeCommand< Command
definitialize
@commands = []
end

defadd_command(cmd)
@commands<< cmd
end

defexecute
@commands.each {|cmd| cmd.execute }
end

defundo_execute
@commands.reverse.each {|cmd| cmd.undo_execute }
end

defdescription
description =""
@commands.each {|cmd| description += cmd.description +"\n"}
description
end
end

コーディングは以上です。実際に動かしてみます。

command_list = CompositeCommand.new
command_list.add_command(CreateFile.new("file1.txt","hello world\n"))
command_list.add_command(CopyFile.new("file1.txt","file2.txt"))
command_list.add_command(DeleteFile.new("file1.txt"))

command_list.execute
puts(command_list.description)
#=> Create file : file1.txt
#=> Copy file : file1.txt to file2.txt
#=> Delete file : file1.txt

# 処理を取り消すコマンド
command_list.undo_execute
#=> file2が消えている

このように使う側はCommandの本当の実装は知りませんが、ファイルの作成、ファイルのコピー、ファイルの削除のコマンドを実行できました。

🚕サンプルソース

🐡参考リンク

🖥 VULTRおすすめ

VULTR」はVPSサーバのサービスです。日本にリージョンがあり、最安は512MBで2.5ドル/月($0.004/時間)で借りることができます。4GBメモリでも月20ドルです。 最近はVULTRのヘビーユーザーになので、「ここ」から会員登録してもらえるとサービス開発が捗ります!

📚 おすすめの書籍

Rails/Modelバリデーションコールバック変更前後の値の確認値の保存・更新アソシエーション削除メソッドSQLの実行日付カラムの設定便利なDB関連設定読込み専用(Read Only)Concern(共通処理)クエリTipsRails/Controllerrenderレシピ集HTTPステータスシンボルIPの取得についてStrong ParametersControllerのTipsRails/ViewHAMLチートシート画像アップロードフォームS3への画像アップロードForm Objectフォームヘルパー検索可能なselectタグenum - selectタグシンプルな検索ボックス別ウィンドウ・フォームRailsいろいろi18nについてRails.cacheメール送信ロギングCapistrano3でデプロイセッション管理環境ごとのYAML設定読込xx分前の時間表記Tipsいろいろ便利ライブラリ簡単Webmock:VCRN+1対策:bullet環境変数の管理: dotenvi18nサポート: i18n-tasksLDAP:net-ldapヘッダ:secureheadersrack-mini-profileractiverecord-precountカバレッジ計測パンくずリスト+MetadataRSpecの記法自動修正アプリランキング取得Unicorn導入手順unicorn-worker-killerRSpecController SpecCapybaraとヘッドレスChromeRequest SpecAPI認証 Spec便利Tipsデザインパターン概要アブストラクトファクトリビルダファクトリメソッドアダプタコンポジットデコレータプロキシコマンドインタプリタイテレータオブザーバストラテジテンプレートメソッドRuby基礎文字列/String配列/Arrayハッシュ/Hash構造体/StructSpawn(コマンド実行)BundlerについてTipsRails 5.1へのアップデートRails 5へのアップデートrbenvバージョンアップpumaをsystemdで動かすURI.encodeとCGI.escapeURLのパラメータを変更処理時間を計測画像JPEG/PNG/GIF判定トラブルシュートNo route matches assets

[8]ページ先頭

©2009-2025 Movatter.jp