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

第5回 Compositeパターンを導き出すための準備

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

Imports System
Imports NUnit.Framework
Imports DesignPatterns.Core.Composite

Namespace DesignPatterns.Tests.Composite

  ' StoriesWriterのテスト・クラス
  <TestFixture()> Public Class StoriesWriterTest

    Private _target As StoriesWriter

    <Test()> Public Sub シンプルなXMLを出力する()
      _target = New StoriesWriter(CreateSimpleStories())

      Dim expected As String = _
       "<stories>" & _
        "<story no=""1"" priority=""5"">" & _
          "<content>ストーリーをXMLで出力する。</content>" & _
          "<task no=""1"" storyNo=""1"">" & _
            "<actualPoint isOver=""True"">2.0</actualPoint>" & _
            "<estimatedPoint>1.5</estimatedPoint>" & _
            "<content>StoryWriterを作成する。</content>" & _
          "</task>" & _
        "</story>" & _
      "</stories>"

      Assert.AreEqual(expected, _target.GetContents(), _
        "出力されたXMLが違います。")
    End Sub

    ' シンプルなストーリーの集合を生成する

    Private Function CreateSimpleStories() As Stories
      Dim myStories As Stories = New Stories

      Dim myStory As Story = New Story(1)
      myStory.Priority = 5
      myStory.Content = "ストーリーをXMLで出力する。"

      Dim myTask As Task = New Task(1)
      myTask.ActualPoint = 2.0F
      myTask.EstimatedPoint = 1.5F
      myTask.Content = "StoryWriterを作成する。"

      myStory.Add(myTask)
      myStories.Add(myStory)

      Return myStories
    End Function

  End Class

End Namespace
StoriesWriterクラスのテスト・コード(VB.NET)
 
Imports System
Imports System.Text

Namespace DesignPatterns.Core.Composite

  ' StoriesWriterクラス
  Public Class StoriesWriter

    Private _stories As Stories

    ' コンストラクタ
    Public Sub New(ByVal myStories As Stories)
      Me._stories = myStories
    End Sub

    ' XMLを文字列で出力する
    Public Function GetContents() As String
      Dim xml As StringBuilder = New StringBuilder
      xml.Append("<stories>")

      For Each myStory As Story In _stories
        xml.Append("<story")
        xml.Append(" no=""")
        xml.Append(myStory.No.ToString())
        xml.Append("""")
        xml.Append(" priority=""")
        xml.Append(myStory.Priority.ToString())
        xml.Append(""">")

        xml.Append("<content>")
        xml.Append(myStory.Content)
        xml.Append("</content>")

        For Each myTask As Task In myStory
          xml.Append("<task")
          xml.Append(" no=""")
          xml.Append(myTask.No.ToString())
          xml.Append("""")
          xml.Append(" storyNo=""")
          xml.Append(myTask.StoryNo.ToString())
          xml.Append(""">")

          xml.Append("<actualPoint")
          xml.Append(" isOver=""")
          xml.Append(myTask.IsOverPoint().ToString())
          xml.Append(""">")
          xml.Append(myTask.ActualPoint.ToString("##.0"))
          xml.Append("</actualPoint>")

          xml.Append("<estimatedPoint>")
          xml.Append(myTask.EstimatedPoint.ToString("##.0"))
          xml.Append("</estimatedPoint>")

          xml.Append("<content>")
          xml.Append(myTask.Content)
          xml.Append("</content>")

          xml.Append("</task>")
        Next

        xml.Append("</story>")
      Next

      xml.Append("</stories>")

      Return xml.ToString()
    End Function

  End Class

End Namespace
リファクタリング前のStoriesWriterクラスの実装コード(VB.NET)
 
Imports System
Imports System.Text

Namespace DesignPatterns.Core.Composite

  Public Class StoriesWriter

    ……中略……


    ' メソッドの抽出が行われたGetContentsメソッド

    Public Function GetContents() As String
      Dim xml As StringBuilder = New StringBuilder
      WriteStoriesTo(xml)
      Return xml.ToString()
    End Function

    ' すべてのストーリーを出力する

    Private Sub WriteStoriesTo(ByVal xml As StringBuilder)
      xml.Append("<stories>")

      For Each myStory As Story In _stories
        xml.Append("<story")
        xml.Append(" no=""")
        xml.Append(myStory.No.ToString())
        xml.Append("""")
        xml.Append(" priority=""")
        xml.Append(myStory.Priority.ToString())
        xml.Append(""">")

        WriteStoryContentTo(xml, myStory)
        WriteTasksTo(xml, myStory)

        xml.Append("</story>")
      Next

      xml.Append("</stories>")

    End Sub

    ' ストーリーの内容を出力する
    Private Sub WriteStoryContentTo(ByVal xml As StringBuilder, _
ByVal myStory As Story)
      xml.Append("<content>")
      xml.Append(myStory.Content)
      xml.Append("</content>")
    End Sub

    ' すべてのタスクを出力する

    Private Sub WriteTasksTo(ByVal xml As StringBuilder, ByVal myStory As Story)
      For Each myTask As Task In myStory
        xml.Append("<task")
        xml.Append(" no=""")
        xml.Append(myTask.No.ToString())
        xml.Append("""")
        xml.Append(" storyNo=""")
        xml.Append(myTask.StoryNo.ToString())
        xml.Append(""">")

        WriteTaskActualPointTo(xml, myTask)
        WriteTaskEstimatedPointTo(xml, myTask)
        WriteTaskContentTo(xml, myTask)

        xml.Append("</task>")
      Next
    End Sub

    ' タスクの実測ポイントを出力する

    Private Sub WriteTaskActualPointTo(ByVal xml As StringBuilder, _
ByVal myTask As Task)
      xml.Append("<actualPoint")
      xml.Append(" isOver=""")
      xml.Append(myTask.IsOverPoint().ToString())
      xml.Append(""">")
      xml.Append(myTask.ActualPoint.ToString("##.0"))
      xml.Append("</actualPoint>")
    End Sub

    ' タスクの予定ポイントを出力する

    Private Sub WriteTaskEstimatedPointTo(ByVal xml As StringBuilder, _
ByVal myTask As Task)
      xml.Append("<estimatedPoint>")
      xml.Append(myTask.EstimatedPoint.ToString("##.0"))
      xml.Append("</estimatedPoint>")
    End Sub

    ' タスクの内容を出力する

    Private Sub WriteTaskContentTo(ByVal xml As StringBuilder, ByVal myTask As Task)
      xml.Append("<content>")
      xml.Append(myTask.Content)
      xml.Append("</content>")
    End Sub

  End Class

End Namespace
Collecting Parameterパターンが適用されたStoriesWriterクラス(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 記事ランキング

本日 月間