VBのWithを使うと可読性が下がる気がする。
VB、VBAにはWith
という構文があります。
このWithを使うとソースコードの可読性が下がるような気がするんです。
Withとはどのような構文か
指定したオブジェクトをステートメント内だけオブジェクトの宣言の省略が可能になる。
たとえば、FooというオブジェクトをWithに指定した場合、
With Foo .Attr = 1 .Run End With
と言った風
どのようなときに使うか
例えば、こういう風に1つのオブジェクトに対して複数の操作を行うとします。
Dim Foo As FooObject Foo = New FooObject Foo.Attr = 1 Foo.State = "Run" Foo.Mode = FOO_MODE_NORMAL Foo.Run
Foo.
が重複しているのでちょっと冗長に感じしまうかもしれません。
そこで、With
を使うと下のように束ねることができます。
Dim Foo As FooObject Foo = New FooObject With Foo .Attr = 1 .State = "Run" .Mode = FOO_MODE_NORMAL .Run end With
こういったふうに、Withで指定したオブジェクトの宣言を省略する事ができます。
こうすることで、同一のオブジェクトに対する複数の操作を簡略化して読みやすくすることができる、と謳われています。
なぜ可読性が下がるのか
これ、自然言語での主語をオブジェクト、動詞をメソッドと置き換えて考えてみると、
主語を省略して動詞だけ言ってるような状態なんですね。
例えば、「本を読んだ」を「読んだ」としか言わない状態です。
文脈として考えるなら、それより前に「本」の話が出ているはずです。
なので、「本」をWithに指定した、と考えれば「読んだ」がメソッドとして考える事ができます。
コレだけ聞くと、なんでそれで可読性が下がるの?とお思いでしょう。
例えば、このように幾つものオブジェクトに対し操作する関数があったとします。
Sub Foo( Bar As BarObject ) With Bar Dim Baz as BazObject Baz = new BazObject Dim Zoo As ZooAbject Zoo = new ZooObject Baz.Attr = 1 Zoo.Attr = 1 .Attr = 1 Bar.Str = "1" Zoo.Str = "1" .Str = "1" end With End Sub
どうですか?
主語がないメソッドはちょっと読みにくく感じませんか?
それそのはず、Withで指定したオブジェクトはコードを読む時にどのオブジェクトがWith指定されているか、頭の片隅に置いて置く必要があります。
また、他のオブジェクトは主語があるのにWith指定したオブジェクトは主語がないため、またコードに一貫性がなく、読みづらい印象を受けます。
こういった観点から、Withを使うと読みにくく感じてしまうわけです。
ネストができてしまう
おまけですが、このWithもネストができてしまいます。
このネストがますます可読性を下げてしまうんじゃないかなと考えています。
Class FooObject Public Sub Run() Console.WriteLine("Foo.Object") End Sub End Class Class BarObject Public Sub Run() Console.WriteLine("Bar.Object") End Sub End Class Sub Main() Dim Foo As FooObject Foo = New FooObject With Foo Dim Bar As BarObject Bar = New BarObject With Bar .Run() End With .Run() Console.ReadLine() End With End Sub
実行結果
Bar.Object Foo.Object
これでWithステートメントが長い行だった場合、ますます理解を困難にさせてしまうと思います。
他の言語にはない
このWithステートメントですが、対応している言語は他に知りません。
少なくとも、C#、C/C++、Rubyでは見たことがありません。
これは、他の言語をやっている人にとっては全くの未知の制御構文で、
他の言語をメインにやってる人が緊急時にVBを触った場合、リファレンスを読む必要が出てしまいます。
こういった観点から、驚き最小の法則
に従っておらず、読みにくく感じてしまう人もいるかもしれません。
改善策
Private Sub AddCustomer() Dim theCustomer As New Customer With theCustomer .Name = "Coho Vineyard" .URL = "http://www.cohovineyard.com/" .City = "Redmond" End With With theCustomer.Comments .Add("First comment.") .Add("Second comment.") End With End Sub Public Class Customer Public Property Name As String Public Property City As String Public Property URL As String Public Property Comments As New List(Of String) End Class
- Withステートメントは長くならないようにします。
コーディングルールとして策定するなら
もし、Withの使い方についてコーディングルールを作るなら、以下のようにします。
- Withのステートメント内はWithに指定したのオブジェクトのみを使用する
- Withのネストは行わない
参考文献・サイト
With...End With Statement (Visual Basic)
プリンシプル オブ プログラミング3年目までに身につけたい一生役立つ101の原理原則
- 作者: 上田勲
- 出版社/メーカー: 秀和システム
- 発売日: 2016/03/23
- メディア: 単行本
- この商品を含むブログ (9件) を見る
リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)
- 作者: Dustin Boswell,Trevor Foucher,須藤功平,角征典
- 出版社/メーカー: オライリージャパン
- 発売日: 2012/06/23
- メディア: 単行本(ソフトカバー)
- 購入: 68人 クリック: 1,802回
- この商品を含むブログ (135件) を見る