プログラミングにおいて、コードの設計は非常に重要です。
効率的で保守しやすいコードを書くために、多くのエンジニアが「デザインパターン」を利用しています。
デザインパターンとは、よくあるソフトウェア設計の問題に対する、再利用可能な解決策のことです。
本記事では、VBScriptという古典的なスクリプト言語を使いながら、デザインパターンの基本的な考え方を学び、実際に適用する方法を解説します。
デザインパターンとは?
デザインパターンとは、特定の課題に対して最適な解決策を提供するテンプレートです。
これを用いることで、開発者は以下の利点を得ることができます:
- コードの再利用性の向上
- 保守性の向上
- 開発時間の短縮
デザインパターンは大きく3つに分類されます:
- 生成パターン:オブジェクトの生成に関するパターン(例:シングルトン、ファクトリーパターン)
- 構造パターン:オブジェクトの構造を整理するためのパターン(例:デコレータ、アダプタパターン)
- 振る舞いパターン:オブジェクト間の連携や責任の分担を整理するパターン(例:オブザーバー、コマンドパターン)
VBScriptとデザインパターンの相性
VBScriptは、特にウェブブラウザや簡単な自動化スクリプトで利用される軽量スクリプト言語ですが、オブジェクト指向の考え方をサポートしており、デザインパターンを実装することも可能です。
VBScriptは、クラスの概念こそ持たないものの、関数やプロシージャ、オブジェクトの仕組みを利用することで多くのデザインパターンを適用できます。
VBScriptでのデザインパターンの実装方法
シングルトンパターン
シングルトンパターンは、特定のクラスが一つのインスタンスしか持たないことを保証します。
VBScriptでは、クラス内でインスタンスを管理することでシングルトンを実現できます。
Class Singleton
Private SharedInstance
Private Sub Class_Initialize()
' 初期化処理
End Sub
Public Function GetInstance()
If IsEmpty(SharedInstance) Then
Set SharedInstance = New Singleton
End If
Set GetInstance = SharedInstance
End Function
End Class
' シングルトンの使用例
Dim obj
Set obj = Singleton.GetInstance()
このコードでは、GetInstanceメソッドがインスタンスを一度だけ生成し、それ以降は同じインスタンスを返します。
ファクトリーパターン
ファクトリーパターンでは、オブジェクトの生成を専用のメソッドに委任することで、依存性を減らし、柔軟な拡張を可能にします。
Class AnimalFactory
Public Function CreateAnimal(animalType)
Select Case animalType
Case "Dog"
Set CreateAnimal = New Dog
Case "Cat"
Set CreateAnimal = New Cat
Case Else
Set CreateAnimal = Nothing
End Select
End Function
End Class
Class Dog
Public Sub Speak()
MsgBox "Woof!"
End Sub
End Class
Class Cat
Public Sub Speak()
MsgBox "Meow!"
End Sub
End Class
' ファクトリーパターンの使用例
Dim factory, animal
Set factory = New AnimalFactory
Set animal = factory.CreateAnimal("Dog")
animal.Speak()
ファクトリークラスが、オブジェクトの生成を担当し、クライアント側は動物の種類だけを指定すれば、具体的なオブジェクトの生成はファクトリに任せることができます。
ストラテジーパターン
ストラテジーパターンでは、異なるアルゴリズムをクラスとして定義し、状況に応じてそれらを動的に切り替えることが可能です。
Class Context
Private strategy
Public Sub SetStrategy(s)
Set strategy = s
End Sub
Public Sub ExecuteStrategy()
strategy.Algorithm
End Sub
End Class
Class StrategyA
Public Sub Algorithm()
MsgBox "Strategy A"
End Sub
End Class
Class StrategyB
Public Sub Algorithm()
MsgBox "Strategy B"
End Sub
End Class
' ストラテジーパターンの使用例
Dim context, strategyA, strategyB
Set context = New Context
Set strategyA = New StrategyA
Set strategyB = New StrategyB
' Strategy A を使用
context.SetStrategy strategyA
context.ExecuteStrategy()
' Strategy B に切り替え
context.SetStrategy strategyB
context.ExecuteStrategy()
クライアントは、Contextクラスを通じて異なる戦略(アルゴリズム)を動的に変更することができます。
オブザーバーパターン
オブザーバーパターンでは、あるオブジェクトの状態が変化した際に、その変化を監視している他のオブジェクト(オブザーバー)に通知します。
このパターンは、イベント駆動型のプログラムでよく使用されます。
Class Subject
Private observers
Private Sub Class_Initialize()
Set observers = CreateObject("Scripting.Dictionary")
End Sub
Public Sub AddObserver(o)
observers.Add observers.Count + 1, o
End Sub
Public Sub NotifyObservers()
Dim o
For Each o In observers
o.Update
Next
End Sub
End Class
Class Observer
Public Sub Update()
MsgBox "Observer Notified!"
End Sub
End Class
' オブザーバーパターンの使用例
Dim subject, observer1, observer2
Set subject = New Subject
Set observer1 = New Observer
Set observer2 = New Observer
subject.AddObserver observer1
subject.AddObserver observer2
' 状態変更を通知
subject.NotifyObservers()
この例では、Subjectが複数のObserverを持ち、NotifyObserversメソッドを呼び出すことで、全てのオブザーバーに通知します。
デコレーターパターン
デコレーターパターンでは、オブジェクトに動的に機能を追加することができます。
基本的なクラスに対して、追加の責務を与えるために使用されます。
Class Component
Public Sub Operation()
MsgBox "Basic Operation"
End Sub
End Class
Class Decorator
Private component
Public Sub SetComponent(c)
Set component = c
End Sub
Public Sub Operation()
component.Operation
MsgBox "Added Operation by Decorator"
End Sub
End Class
' デコレーターパターンの使用例
Dim component, decorator
Set component = New Component
Set decorator = New Decorator
decorator.SetComponent component
decorator.Operation()
DecoratorクラスがComponentクラスをラップし、元の機能に加えて追加の動作を実行します。
デザインパターンの適用例
これまでに紹介したパターンは、さまざまな場面で利用できます。
シングルトンパターンは設定情報の管理、ファクトリーパターンはオブジェクト生成の集中管理に役立ちます。
ストラテジーパターンは異なるアルゴリズムを容易に切り替えたい場合、オブザーバーパターンはイベント通知システムの設計に、デコレーターパターンは既存のオブジェクトに機能を追加する場合に使えます。
まとめ
この記事では、VBScriptでのデザインパターンの実装を紹介しました。
シングルトン、ファクトリー、ストラテジー、オブザーバー、デコレーターパターンといった代表的なデザインパターンを使うことで、再利用性の高い保守性のあるコードが書けるようになります。
VBScriptはオブジェクト指向プログラミングの機能が限定的ですが、デザインパターンを適用することで効率的な設計が可能です。
演習問題と解答例
この記事の内容を基にした演習問題を通じて、実際に手を動かしながら学習を進めましょう。
演習問題1: オブザーバーパターンの実装
NewsPublisherクラスを作成し、複数のSubscriberクラスがそのニュースを購読して通知を受け取る仕組みを実装してください。
ニュースが更新された際に、全ての購読者に通知が送られるようにしてください。
演習1:解答例
Class NewsPublisher
Private subscribers
Private Sub Class_Initialize()
Set subscribers = CreateObject("Scripting.Dictionary")
End Sub
Public Sub AddSubscriber(s)
subscribers.Add subscribers.Count + 1, s
End Sub
Public Sub NotifySubscribers(news)
Dim s
For Each s In subscribers
s.Update(news)
Next
End Sub
End Class
Class Subscriber
Public Sub Update(news)
MsgBox "Received News: " & news
End Sub
End Class
' 使用例
Dim publisher, subscriber1, subscriber2
Set publisher = New NewsPublisher
Set subscriber1 = New Subscriber
Set subscriber2 = New Subscriber
publisher.AddSubscriber subscriber1
publisher.AddSubscriber subscriber2
' ニュースを通知
publisher.NotifySubscribers "New Article Published!"
演習問題2: デコレーターパターンの実装
Carクラスに、Driveメソッドを持たせ、デコレーターでSportsCarやLuxuryCarとして追加機能(例えば、スピードの表示や快適なドライブメッセージ)を付け加える実装をしてください。
演習2:解答例
Class Car
Public Sub Drive()
MsgBox "Driving a car."
End Sub
End Class
Class SportsCarDecorator
Private car
Public Sub SetCar(c)
Set car = c
End Sub
Public Sub Drive()
car.Drive
MsgBox "Driving fast with a sports car!"
End Sub
End Class
Class LuxuryCarDecorator
Private car
Public Sub SetCar(c)
Set car = c
End Sub
Public Sub Drive()
car.Drive
MsgBox "Driving in luxury!"
End Sub
End Class
' 使用例
Dim car, sportsCar, luxuryCar
Set car = New Car
Set sportsCar = New SportsCarDecorator
Set luxuryCar = New LuxuryCarDecorator
sportsCar.SetCar car
luxuryCar.SetCar car
' スポーツカーとして運転
sportsCar.Drive()
' ラグジュアリーカーとして運転
luxuryCar.Drive()