私はFarPoint社のSpread Sheetを多用します。
シートの行を削除したり、コピーやペーストをあちこちの画面(Form)で使いたくなります。このコードをそれぞれの画面で書いていたのでは、メンテナンス上よくありません。
VBでは、共通関数をModuleに書くことはできますが美しくありません。
コントロールに新しい機能追加する一つの方法は、そのコントロールを拡張するカスタムコントロールを作ることです。
しかしカスタムコントロールの作成は少し大げさでメンテナンスに手間取りそうなので別な方法を考えます。いま、これらの処理を受け持つクラス(仮にMySpreadとします)を一つ作ります。
FormではSpreadを配置し、Spreadのデザインやデータの入出力はすべてFormで処理します。MySpreadではSpreadに対応したContextMenuStripのインスタンスを作成し、右クリックしたときのプルダウンメニューの処理をこちらで行うことにします。
FormでMySpreadのインスタンスをつくり、Form上のSpreadとのリンクを付けておきます。
MySpreadの中で行削除や、コピーアンドペースト等のメソッドを準備してやれば、各Formでこれらのコードを書く必要はありません。
Public Class MySpread Private WithEvents m_Spd As FpSpread Private m_Sheet As SheetView Private m_ContextMenuStrip As New ContextMenuStrip Private WithEvents m_tsmi挿入 As New ToolStripMenuItem ' m_tsmiコピー、m_tsmi切取、m_tsmi貼付、 m_tsmi削除 等以下省略 Private m_activeRow As Integer Private m_コピー元 As Integer Private m_コピー中 As Boolean Sub New(ByRef Spd As FpSpread, ByVal shtIdx As Integer) m_Spd = Spd m_Sheet = Spd.Sheets(shtIdx) m_tsmi挿入.Text = "挿入" m_tsmiコピー.Text = "コピー" m_tsmi切取.Text = "切取" m_tsmi貼付.Text = "貼付" m_tsmi削除.Text = "削除" m_ContextMenuStrip.Items.Add(m_tsmi挿入) m_ContextMenuStrip.Items.Add(m_tsmiコピー) m_ContextMenuStrip.Items.Add(m_tsmi切取) m_ContextMenuStrip.Items.Add(m_tsmi貼付) m_ContextMenuStrip.Items.Add(m_tsmi削除) End Sub Private Sub FpSpead_CellClick(ByVal sender As Object, ByVal e As FarPoint.Win.Spread.CellClickEventArgs) Handles m_Spd.CellClick If blninit = False Then Exit Sub activeRow = e.Row End Sub Private Sub tsmi挿入_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles m_tsmi挿入.Click m_Sheet.AddRows(activeRow, 1) End Sub ' 以下省略 Private Sub tsmiコピー_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles m_tsmiコピー.Click End Sub Private Sub tsmi切取_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles m_tsmi切取.Click End Sub Private Sub tsmi貼付_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles m_tsmi貼付.Click End Sub Private Sub tsmi削除_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles m_tsmi削除.Click End Sub End Class
実はこの話は以前ご紹介しました、[複数コントロールのセットを何度も使う]と内容的には同じことです。この原始的方法は、結構役立ちます。
とはいえOOPの工夫をもっと体系的に研究する必要があると考えています。デザインパターンを少し勉強しましたが、デザインパターンの技術を採用する場面が余りありません。
私のOOPの勉強は10数年前のJavaに始まり、確か2002年ころから.NETを使用してプログラムを書いていますので、特にVB.NETは目をつむっても書けるくらい慣れ親しんでいますが、デザインパターンはほんの一掴みほどしか利用していません。
理由がよくわかりません。一つには私が、デザインパターンを使いこなすほど勉強していないからだと思いますが、開発している内容も向き不向きがあるかもしれません。
ライブラリ等似たような話題が沢山あって、それらを体系的に構築しなければいけないケースでは、確かにインタフェース(に代表されるデザインパターンの技術)をうまく使う必要があると思います。が、10万行にも満たない事務アプリでは、似たようなクラスあるいは幾層もの階層をもったクラスを余り使いません。このようなケースでデザインパターンを使った高級な技術の必要性を感じていません。
それともう一つ現実的な問題として、そのプロジェクトに投入できる技術者の質と量の問題があると思います。マンパワーを十分かけた大きなシステムならいざ知らず、数万行のアプリケーションの作成では、高級な技術者がそろっているわけではありませんので、難しいコードを使うと後々メンテナンスの維持ができなくなる恐れがあります。その意味でできるだけ分かりやすい原始的コードを書く必要があります。
プログラムの評価の本で、[バグを抑えるためにはローテクを使え]というような文章を読んだことがあります。
確かにそうかもしれないと思っています。
だからといってデザインパターンのような体系的なプログラム技術が不要と言う訳ではありません。十分勉強して機会ある毎に利用すべきだと思います。
(ただし、趣味から言うと、私はデザインパターンより、泥臭いがしかし示唆に富んだJoshua Blochの[Effective Java]の方が好きで、さしあたり、この本を熟読玩味するところから始めようと考えています。)