連載
.NETで始めるデザインパターン

第4回 リファクタリングにより導き出すTemplate Methodパターン

太陽システム株式会社 中西 庸文
Microsoft MVP 2005 - Solutions Architect)
2005/04/23

 
Imports System

Namespace DesignPatterns.Core.TemplateMethod

  ' TextFormatterクラス
  Public MustInherit Class TextFormatter

    '「価値」を出力する
    Public MustOverride Function Format(ByVal myXpValues As XpValues) As String

    ' タイトルを取得する
    Protected Function GetTitleFor(ByVal myXpValues As XpValues) As String
      Return myXpValues.Name & "の" & myXpValues.Count.ToString() & "つの価値"
    End Function

  End Class

End Namespace
TextFormatterクラス(VB.NET)
 
Imports System
Imports System.Text

Namespace DesignPatterns.Core.TemplateMethod

  ' PlainTextFormatterクラス
  Public Class PlainTextFormatter : Inherits TextFormatter

    ' 「価値」を出力する
    Public Overrides Function Format(ByVal myXpValues As XpValues) As String
      Dim builder As StringBuilder = New StringBuilder
      builder.Append(GetTitleFor(myXpValues) & vbCrLf)
      For Each xpValue As String In myXpValues
        builder.Append("・" & xpValue & vbCrLf)
      Next
      Return builder.ToString()
    End Function

  End Class

End Namespace
PlainTextFormatterクラス(VB.NET)
 
Imports System
Imports System.Text

Namespace DesignPatterns.Core.TemplateMethod

  ' HtmlTextFormatterクラス
  Public Class HtmlTextFormatter : Inherits TextFormatter

    ' 「価値」を出力する
    Public Overrides Function Format(ByVal myXpValues As XpValues) As String
      Dim builder As StringBuilder = New StringBuilder
      builder.Append("<p>" & GetTitleFor(myXpValues) & "</p>" & vbCrLf)
      builder.Append("<ul>" & vbCrLf)
      For Each xpValue As String In myXpValues
        builder.Append("<li>" & xpValue & vbCrLf)
      Next
      builder.Append("</ul>" & vbCrLf)
      Return builder.ToString()
    End Function

  End Class

End Namespace
HtmlTextFormatterクラス(VB.NET)
 
Imports System
Imports System.Text

Namespace DesignPatterns.Core.TemplateMethod

  Public Class HtmlTextFormatter : Inherits TextFormatter

    ' メソッドの抽出が行われてComposed MethodになったFormatメソッド
    Public Overrides Function Format(ByVal myXpValues As XpValues) As String
      Dim builder As StringBuilder = New StringBuilder
      builder.Append(TitleText(myXpValues))
      builder.Append(ValuesHeaderText())
      For Each xpValue As String In myXpValues
        builder.Append(EachValueText(xpValue))
      Next
      builder.Append(ValuesFooterText())
      Return builder.ToString()
    End Function

    ' タイトルの出力
    Private Function TitleText(ByVal myXpValues As XpValues) As String
      Return "<p>" & GetTitleFor(myXpValues) & "</p>" & vbCrLf
    End Function

    ' ヘッダの出力
    Private Function ValuesHeaderText() As String
      Return "<ul>" & vbCrLf
    End Function

    ' 価値の出力
    Private Function EachValueText(ByVal xpValue As String) As String
      Return "<li>" & xpValue & vbCrLf
    End Function

    ' フッタの出力
    Private Function ValuesFooterText() As String
      Return "</ul>" & vbCrLf
    End Function

  End Class

End Namespace
Composed Methodパターンが適用されたHtmlTextFormatterクラス(VB.NET)
 
Imports System
Imports System.Text

Namespace DesignPatterns.Core.TemplateMethod

  Public Class PlainTextFormatter : Inherits TextFormatter

    ' メソッドの抽出が行われてComposed MethodになったFormatメソッド
    Public Overrides Function Format(ByVal myXpValues As XpValues) As String
      Dim builder As StringBuilder = New StringBuilder
      builder.Append(TitleText(myXpValues))
      builder.Append(ValuesHeaderText())
      For Each xpValue As String In myXpValues
        builder.Append(EachValueText(xpValue))
      Next
      builder.Append(ValuesFooterText())
      Return builder.ToString()
    End Function

    ' タイトルの出力

    Private Function TitleText(ByVal myXpValues As XpValues) As String
      Return GetTitleFor(myXpValues) & vbCrLf
    End Function

    ' ヘッダの出力(Nothingを返す)
    Private Function ValuesHeaderText() As String
      Return Nothing
    End Function

    ' 価値の出力
    Private Function EachValueText(ByVal xpValue As String) As String
      Return "・" & xpValue & vbCrLf
    End Function

    ' フッタの出力(Nothingを返す)
    Private Function ValuesFooterText() As String
      Return Nothing
    End Function

  End Class

End Namespace
Composed Methodパターンが適用されたPlainTextFormatterクラス(VB.NET)
 
Imports System
Imports System.Text

Namespace DesignPatterns.Core.TemplateMethod

  Public MustInherit Class TextFormatter

    ' HtmlTextFormatterクラスから引き上げられたFormatメソッド
    Public MustOverride Function Format(ByVal myXpValues As XpValues) As String
    Public Overridable Function Format(ByVal myXpValues As XpValues) As String
      Dim builder As StringBuilder = New StringBuilder
      builder.Append(TitleText(myXpValues))
      builder.Append(ValuesHeaderText())
      For Each xpValue As String In myXpValues
        builder.Append(EachValueText(xpValue))
      Next
      builder.Append(ValuesFooterText())
      Return builder.ToString()
    End Function

    ' 抽象メソッドとして定義したTitleTextメソッド
    Protected MustOverride Function TitleText(ByVal myXpValues As XpValues) As String

    ' 抽象メソッドとして定義したValuesHeaderTextメソッド
    Protected MustOverride Function ValuesHeaderText() As String

    ' 抽象メソッドとして定義したEachValueTextメソッド
    Protected MustOverride Function EachValueText(ByVal xpValue As String) As String

    ' 抽象メソッドとして定義したValuesFooterTextメソッド
    Protected MustOverride Function ValuesFooterText() As String
    ……中略……
  End Class

End Namespace
メソッドが引き上げてこられたTextFormatter クラス(VB.NET)
 
Imports System
Imports System.Text

Namespace DesignPatterns.Core.TemplateMethod

  Public Class HtmlTextFormatter : Inherits TextFormatter

    ' 削除されたFormatメソッド
    Public Overrides Function Format(ByVal myXpValues As XpValues) As String
      Dim builder As StringBuilder = New StringBuilder
      builder.Append(TitleText(myXpValues))
      builder.Append(ValuesHeaderText())
      For Each xpValue As String In myXpValues
        builder.Append(EachValueText(xpValue))
      Next
      builder.Append(ValuesFooterText())
      Return builder.ToString()
    End Function

    ' オーバーライドされたTitleTextメソッド
    Protected Overrides Function TitleText(ByVal myXpValues As XpValues) As String
      Return "<p>" & GetTitleFor(myXpValues) & "</p>" & vbCrLf
    End Function

    ' オーバーライドされたValuesHeaderTextメソッド
    Protected Overrides Function ValuesHeaderText() As String
      Return "<ul>" & vbCrLf
    End Function

    ' オーバーライドされたEachValueTextメソッド
    Protected Overrides Function EachValueText(ByVal xpValue As String) As String
      Return "<li>" & xpValue & vbCrLf
    End Function

    ' オーバーライドされたValuesFooterTextメソッド
    Protected Overrides Function ValuesFooterText() As String
      Return "</ul>" & vbCrLf
    End Function

  End Class

End Namespace
引き上げたメソッドが削除され、抽象メソッドをオーバーライドする形となったHtmlTextFormatterクラス(VB.NET)
 
Imports System
Imports System.Text

Namespace DesignPatterns.Core.TemplateMethod

  Public Class PlainTextFormatter : Inherits TextFormatter

    Public Overrides Function Format(ByVal myXpValues As XpValues) As String
      Dim builder As StringBuilder = New StringBuilder
      builder.Append(TitleText(myXpValues))
      builder.Append(ValuesHeaderText())
      For Each xpValue As String In myXpValues
        builder.Append(EachValueText(xpValue))
      Next
      builder.Append(ValuesFooterText())
      Return builder.ToString()
    End Function

    ' オーバーライドされたTitleTextメソッド
    Protected Overrides Function TitleText(ByVal myXpValues As XpValues) As String
      Return GetTitleFor(myXpValues) & vbCrLf
    End Function

    ' オーバーライドされたValuesHeaderTextメソッド
    Protected Overrides Function ValuesHeaderText() As String
      Return Nothing
    End Function

    ' オーバーライドされたEachValueTextメソッド
    Protected Overrides Function EachValueText(ByVal xpValue As String) As String
      Return "・" & xpValue & vbCrLf
    End Function

    ' オーバーライドされたValuesFooterTextメソッド
    Protected Overrides Function ValuesFooterText() As String
      Return Nothing
    End Function

  End Class

End Namespace
抽象メソッドをオーバーライドする形となったPlainTextFormatterクラス(VB.NET)
 
Imports System
Imports System.Text

Namespace DesignPatterns.Core.TemplateMethod

  Public Class PlainTextFormatter : Inherits TextFormatter

    ' 削除されたFormatメソッド
    Public Overrides Function Format(ByVal myXpValues As XpValues) As String
      Dim builder As StringBuilder = New StringBuilder
      builder.Append(TitleText(myXpValues))
      builder.Append(ValuesHeaderText())
      For Each xpValue As String In myXpValues
        builder.Append(EachValueText(xpValue))
      Next
      builder.Append(ValuesFooterText())
      Return builder.ToString()
    End Function
    ……中略……
  End Class

End Namespace
引き上げたメソッドが削除されたPlainTextFormatterクラス(VB.NET)
 
Imports System
Imports System.Text

Namespace DesignPatterns.Core.TemplateMethod

  Public MustInherit Class TextFormatter

    ' 仮想メソッドから通常のメソッドへと変更されたFormatメソッド
    Public Overridable Function Format(ByVal myXpValues As XpValues) As String
      Dim builder As StringBuilder = New StringBuilder
      builder.Append(TitleText(myXpValues))
      builder.Append(ValuesHeaderText())
      For Each xpValue As String In myXpValues
        builder.Append(EachValueText(xpValue))
      Next
      builder.Append(ValuesFooterText())
      Return builder.ToString()
    End Function
    ……中略……
  End Class

End Namespace
仮想メソッドから通常のメソッドへの変更が行われたTextFormatterクラス(VB.NET)
 
Imports System
Imports System.Text

Namespace DesignPatterns.Core.TemplateMethod

  Public MustInherit Class TextFormatter
    ……中略……
   
' 抽象メソッドからデフォルトの実装へと置き換えられたValuesHeaderTextメソッド
    Protected MustOverride Function ValuesHeaderText() As String
    Protected Overridable Function ValuesHeaderText() As String
      Return Nothing
    End Function
    ……中略……
    ' 抽象メソッドからデフォルトの実装へと置き換えられたValuesFooterTextメソッド
    Protected MustOverride Function ValuesFooterText() As String
    Protected Overridable Function ValuesFooterText() As String
      Return Nothing
    End Function
   
  End Class

End Namespace
デフォルトの実装が用意されたTextFormatterクラス(VB.NET)
 
Imports System

Namespace DesignPatterns.Core.TemplateMethod

  Public Class PlainTextFormatter : Inherits TextFormatter
    ……中略……
    ' 削除されたValuesHeaderTextメソッド
    Protected Overrides Function ValuesHeaderText() As String
      Return Nothing
    End Function
    ……中略……
    ' 削除されたValuesFooterTextメソッド
    Protected Overrides Function ValuesFooterText() As String
      Return Nothing
    End Function

  End Class

End Namespace
メソッドが削除されたPlainTextFormatterクラス(VB.NET)
 
Imports System
Imports System.Collections

Namespace DesignPatterns.Core.TemplateMethod

  ' XpValuesクラス
  Public Class XpValues : Implements IEnumerable

    Private _name As String
    Private _values As ArrayList = New ArrayList
    Private _formatter As TextFormatter

    ' プライベート・コンストラクタ
    Private Sub New(ByVal name As String, ByVal formatter As TextFormatter)
      Me._name = name
      Me._formatter = formatter
    End Sub

    ' 保持する「価値」をプレーン・テキスト形式で出力できるインスタンスを生成
    Public Shared Function CreatePlainTextFormatableXpValues(ByVal name As String) As XpValues
      Return New XpValues(name, New PlainTextFormatter)
    End Function

    ' 保持する「価値」をHTML形式で出力できるインスタンスを生成

    Public Shared Function CreateHtmlTextFormatableXpValues(ByVal name As String) As XpValues
      Return New XpValues(name, New HtmlTextFormatter)
    End Function

    ' 名前を取得する
    Public ReadOnly Property Name() As String
      Get
        Return _name
      End Get
    End Property

    ' 「価値」の数を取得する

    Public ReadOnly Property Count() As Integer
      Get
        Return _values.Count
      End Get
    End Property

    ' 「価値」を取得する
    Default Public ReadOnly Property Item(ByVal index As Integer) As String
      Get
        Return _values(index).ToString()
      End Get
    End Property

    ' 「価値」を登録する
    Public Sub Add(ByVal xpValue As String)
      _values.Add(xpValue)
    End Sub

    ' XpValues を反復処理できる列挙子を取得する
    Public Function GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
      Return _values.GetEnumerator()
    End Function

    ' 保持する「価値」を出力する

    Public Function Format() As String
      Return _formatter.Format(Me)
    End Function

  End Class

End Namespace
XpValuesクラス(VB.NET)
 
Imports System
Imports System.Text

Namespace DesignPatterns.Core.TemplateMethod

  ' TextFormatterクラス
  Public MustInherit Class TextFormatter

    '「価値」を出力する
    Public Function Format(ByVal myXpValues As XpValues) As String
      Dim builder As StringBuilder = New StringBuilder
      builder.Append(TitleText(myXpValues))
      builder.Append(ValuesHeaderText())
      For Each xpValue As String In myXpValues
        builder.Append(EachValueText(xpValue))
      Next
      builder.Append(ValuesFooterText())
      Return builder.ToString()
    End Function

    ' タイトルの出力
    Protected MustOverride Function TitleText(ByVal myXpValues As XpValues) As String

    ' ヘッダの出力
    Protected Overridable Function ValuesHeaderText() As String
      Return Nothing
    End Function

    ' 価値の出力
    Protected MustOverride Function EachValueText(ByVal xpValue As String) As String

    ' フッタの出力

    Protected Overridable Function ValuesFooterText() As String
      Return Nothing
    End Function

    ' タイトルを取得する
    Protected Function GetTitleFor(ByVal myXpValues As XpValues) As String
      Return myXpValues.Name & "の" & myXpValues.Count.ToString() & "つの価値"
    End Function

  End Class

End Namespace
TextFormatter クラス(VB.NET)
 
Imports System

Namespace DesignPatterns.Core.TemplateMethod

  ' PlainTextFormatterクラス
  Public Class PlainTextFormatter : Inherits TextFormatter

    ' タイトルの出力
    Protected Overrides Function TitleText(ByVal myXpValues As XpValues) As String
      Return GetTitleFor(myXpValues) & vbCrLf
    End Function

    ' 価値の出力
    Protected Overrides Function EachValueText(ByVal xpValue As String) As String
      Return "・" & xpValue & vbCrLf
    End Function

  End Class

End Namespace
PlainTextFormatterクラス(VB.NET)
 
Imports System

Namespace DesignPatterns.Core.TemplateMethod

  ' HtmlTextFormatterクラス

  Public Class HtmlTextFormatter : Inherits TextFormatter

    ' タイトルの出力
    Protected Overrides Function TitleText(ByVal myXpValues As XpValues) As String
      Return "<p>" & GetTitleFor(myXpValues) & "</p>" & vbCrLf
    End Function

    ' ヘッダの出力
    Protected Overrides Function ValuesHeaderText() As String
      Return "<ul>" & vbCrLf
    End Function

    ' 価値の出力
    Protected Overrides Function EachValueText(ByVal xpValue As String) As String
      Return "<li>" & xpValue & vbCrLf
    End Function

    ' フッタの出力
    Protected Overrides Function ValuesFooterText() As String
      Return "</ul>" & vbCrLf
    End Function

  End Class

End Namespace
HtmlTextFormatterクラス(VB.NET)
 
インデックス・ページヘ  「.NETで始めるデザインパターン」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間