投稿数 - 437, コメント - 59536, トラックバック - 156

主語は何か

自分で書いたコードの欠点はなかなか見つからなくても、他人が書いたコードの欠点は嫌という程目に付く。プログラマの目というものは全くもって都合が良い。

どうも他人が書いたメソッドの動詞の意味が逆のような気がしてしょうがない時がある。簡単な例で言えば、Set~、Get~ という類のメソッド名。

呼び出し側のオブジェクトが主語、呼び出し先のオブジェクトが目的語だと私は思っているので、Set~ というメソッド名があれば、メソッドを定義しているオブジェクトに何かを設定するんだなと思う。反対に Get~ は、メソッドを定義しているオブジェクトから何かを取得すると思う。

しかし、よく見かけるのが「Set~ は、メソッドを定義しているオブジェクトが何かを設定する(言い方を変えると、オブジェクトから何かを取得する)」「Get~ は、メソッドを定義しているオブジェクトが何かを取得する(言い方を変えると、オブジェクトに何かを設定する)」という意味になっているコードだ。意味が逆なので、とても気持ち悪い。

但し、Public なメソッドではなく Private なメソッドにその傾向が多い。Public なメソッドは私の考えている意味になっていて、Private なメソッドの場合は逆になるというのは、Private なメソッドの場合は、メソッドを定義しているオブジェクトが主語になるからだろうけど、それってデファクトスタンダード? アクセス修飾子の違いで主語がコロコロ変わると混乱するんだが。でも、Private なメソッドに関しては、主語はそうならざるを得ない、という気持ちも分からないでもない。まぁ一概には言えないのかな。

※追記 - 気持ち悪い(と私が思っている)コード例

// ビュー
class UI
{
    // データソースの値を取得してビューに設定しちゃうよ的メソッド
    private void GetData()
    {
        this.TextBox1.Text = DataSource.GetData();
    }

    // ビューの値をデータソースに設定しちゃうよ的メソッド
    private void SetData()
    {
        DataSource.SetData(this.TextBox1.Text);
    }
}

投稿日時 : 2007年7月31日 12:34

フィードバック

# re: 主語は何か

コード例を希望。

自分はInterfaceの定義のときに混乱した経験がありますね。
StrategyパターンとかTemplateMethodパターンで実装クラスを主語にとるのか、Interfaceを呼び出す側を主語に取るのか…
2007/07/31 13:13 | 凪瀬

# re: 主語は何か

メソッドの呼び出しは、どこから呼ばれるかにかかわりなく、オブジェクトになにかをさせるための表記がおいらは望ましいと思ってます。

なので、hoge.Set(...); ならいついかなる状況でも、hoge に ... をセットするという表現になっているのが良い。

Private だからなんて言われたって、呼び出してる箇所でプライベートかどうかなんてわかんねーものw
2007/07/31 13:21 | とっちゃん

# re: 主語は何か

コード例を追加しました。
めっちゃ極端な例ですが。
2007/07/31 13:41 | 囚人

# re: 主語は何か

うををを、気持ち悪ッ

setter, getter以外の意味でsetXX, getXXってメソッドは気色悪いなぁ。
2007/07/31 13:42 | 凪瀬

# re: 主語は何か

Mr.Tです、こんにちは。

>意味が逆なので、とても気持ち悪い。

激しく間違えそう。
ちゅーか、そこまでするなら「どこから?を」メソッドに書いて欲しいww

private void GetDataFromDataSource()

とか。
2007/07/31 13:57 | Mr.T

# re: 主語は何か

こういう場合だったらおいらは、ToDataSource() とか FromDataSource ってかくな。

このメソッドの役割は getter/setter ではないから、Get/Set(Put)はあまり使わない。

さらに、動詞をつけるとごちゃごちゃする(意味合い的に)からスパッと取っ払っちまったほうがわかりやすいしねw
#この辺は日本人的感覚w
2007/07/31 14:39 | とっちゃん

# re: 主語は何か

確かに、メソッドに主語がない上に目的が...
とっちゃんが言うように、ToDataSource()、FromDataSource()
にするか、「DataSource」というプロパティにした方が、
まだ、少しは許せたかもしれません。
2007/07/31 17:16 | けろ

# re: 主語は何か

囚人さんと全く同じことを昔から考え、そして気持ち悪がっていました。
私なら公開メソッドならば From や To などの静的メンバにするだろうし、非公開メソッドならば少なくとも主語を書くでしょう。
それにしても逆になるのは本当に気持ち悪いのでやめてほしい。
2007/07/31 23:37 | じゃんぬねっと

# re: 主語は何か

個人的に...
Get?の方は、Refresh?とかUpdate?とかInit?とか、を使うかな。
Set?の方は、AssignToDataSourceかな?

>とっちゃん
>こういう場合だったらおいらは、ToDataSource() とか FromDataSource ってかくな。
私の脳内では、ToDataSourceはConvertToDataSourceと変換されてしまうので、なんか違和感あるわ。
2007/07/31 23:48 | かずくん

# re: 主語は何か

>ToDataSourceはConvertToDataSource
Covert の場合、おいらはたとえメンバー変数を使う場合でも、引数にして渡しちゃうな。
なので、ConvertTo( DataSource ); みたいな感じw

でも、メソッドで動詞省略は最近はなるべくしないようにしてる。

なにせ、あとで(1年とか2年後)自分で見てわかんねーんだものw
なので、メソッドの名前は、そのメソッドにどんな仕事をさせてるかで名前付けするように心がけてる(つもりw)。
2007/08/01 13:07 | とっちゃん

# re: 主語は何か

れいです。
ここは初めてです。

日本人は主語がなくてもなんとか会話できますが、英語だとそうはいきませんよね。
ライブラリアンは何を主語だと思って書いてるんでしょうか?
疑問に思って、調べたり、English Nativeなプログラマに聞いたことがあります。
激しく長くなりますがご容赦を。

私の結論から言うと、
メソッドの名称はただの行為を表すだけ、つまり「原形」であって、メソッドに主語はありません。
ただし、オブジェクトに対する状態を聞く場合のみ、
「三人称単数現在形の動詞」を名称にとるメソッドがあります。

後者はICollection.Contains、DataSet.HasChanges、Type.IsArrayなどで、
これは明らかに「呼び出し先オブジェクトが主語」で、英語文法をなぞっていてます。
動詞は「状態」あらわす動詞になります。
これはオブジェクト指向言語特有の名前付けです。

他のメソッドは、「行為」を表す動詞が原形で現れます。
XmlDataSource.GetXmlDocument、Control.CreateGraphics、Array.Sort、
などで、GetXXX、SetXXXもこれにあたります。
明らかに、呼び出し先オブジェクトは主語ではありません。
囚人さんはこのケースで「呼び出し元オブジェクトが主語」と思ってらっしゃるようですが、
本当に、主語は呼び出し元オブジェクトでしょうか?

オブジェクト指向だと混乱しますが、
もともとは関数型言語で、関数の総体としての作用・行為を名称としてつけていました。
例えば、RegisterWindowしてCreateWindowしてSetWindowTextする、といった一連の手続きをまとめて、
CreateMyWindowといった関数名にしていたわけです。
メソッド名は「行為の名称」であって、行為そのものではありませんから、主語はありません。
行為の名称ですから、活用しない動詞の原形を用いるのです。

オブジェクトのメンバメソッドの場合、
オブジェクトが行為を行う側なのか、行われる側なのかは、行為やデザインによります。
instance.Destroy()
なら、呼び出し先が自分自身を破棄するんだと思いますが、
ObjectManager.Destroy( instance )
なら呼び出し先が引数を破棄すると解釈できます。
(後者はDestroyObjectと名称をつけるとよりわかりやすいですが。)

逆に言うと、オブジェクトの意味を考えたとき、
メソッド名や引数、戻り値からメソッドの意味が推測できるよう
名前をつけるべきだということになります。

Set/Getは単語が短く、意味も単純で対になっており、便利なのですが、
Fortranの時には既に、濫用が問題になっていたと記憶しています。
プログラムなんて、なんらかのデータをSetやGetするだけがほとんどなので、問題になるのもわかります。

Set/Getの場合、「どこから」「どこに」という情報が必須になります。
最近の言語、Javaや.NetFrameworkでは
Object.SetValue( from )
というパターンで統一しているようです。
だから違和感があるのでしょう。

ですが、
DataPublisher.SetValue( to )
DataUpdater.SetValue( from, to )
といったデザインも存在しますし、そのほうが良い場合もあります。
Cのコードなどではよく見かけます。

件の例では、取得元も固定、設定先も固定で、Privateですから、
私にはそれほど違和感はありません。
.Net Frameworkをあまり使ってないんだろうな、とは思いますが。
2007/08/01 15:46 | れい

# re: 主語は何か

はじめまして。長いですねぇ、ありがとうございます。
また後でまとめて返信したいと思います。
2007/08/02 15:56 | 囚人

# re: 主語は何か

後輩に説明するためのメモをコピペして編集したらこんなになってしまいました。
すみません・・・

失敗したなぁ
2007/08/03 3:07 | れい

# re: 主語は何か

逆になるソースとかあるんですね・・・
公開する範囲が異なるだけで、オブジェクトを利用するためのインターフェース=メソッドだと思っているので
オブジェクトから値を得る=GetHoge
オブジェクトに値を設定する=SetHoge
でないと気持ち悪い~
2007/08/05 12:26 | ちゃと

# re: 主語は何か

XmlDocument.LoadXml(xml)
はどうでしょう?
これは気になりませんよね?

なら
private void GetData(source) {
this.TextBox1.Text = source.GetData();
}
これはどうですか?
少なくとも文法的には同じですよね。

Get/Setのときはあまりこうゆう使い方をしないので
きになるだけなんじゃないかなぁ
2007/08/06 20:56 | れい

# re: 主語は何か

長い返信を書こうと考えてたら遅くなりました。すみません。


> 後者はICollection.Contains、DataSet.HasChanges、Type.IsArrayなどで、
> これは明らかに「呼び出し先オブジェクトが主語」で、英語文法をなぞっていてます。
> 動詞は「状態」あらわす動詞になります。
> これはオブジェクト指向言語特有の名前付けです。

確かにそうですね。主語は呼び出し先です。状態を訊くメソッドはそうならざるを得ないでしょう。但し、訊いているのはあくまで呼び出し元であって、「(呼び出し元が)呼び出し先の状態がHasChangesかどうか(訊く)」と暗黙的になっている感じです。


> オブジェクト指向だと混乱しますが、
> もともとは関数型言語で、関数の総体としての作用・行為を名称としてつけていました。
> 例えば、RegisterWindowしてCreateWindowしてSetWindowTextする、といった一連の手続きをまとめて、
> CreateMyWindowといった関数名にしていたわけです。
> メソッド名は「行為の名称」であって、行為そのものではありませんから、主語はありません。
> 行為の名称ですから、活用しない動詞の原形を用いるのです。

呼び出し元が Window を Create しているんですよね。主語は呼び出し元です。手続き型言語だと、目的語が関数名の一部になって引数にも現れます。それがオブジェクト指向だと、Window.Create() となるわけで。この時に、Window が主語だとかなり奇妙です。Window が何かを作るわけではありませんから。


> オブジェクトのメンバメソッドの場合、
> オブジェクトが行為を行う側なのか、行われる側なのかは、行為やデザインによります。
> instance.Destroy()
> なら、呼び出し先が自分自身を破棄するんだと思いますが、
> ObjectManager.Destroy( instance )
> なら呼び出し先が引数を破棄すると解釈できます。
> (後者はDestroyObjectと名称をつけるとよりわかりやすいですが。)

これも呼び出し元が instance を Destroy するわけで、instance が自分自身を破棄する、というのとは違う気がします。


> XmlDocument.LoadXml(xml)
> はどうでしょう?
> これは気になりませんよね?

> なら
> private void GetData(source) {
> this.TextBox1.Text = source.GetData();
> }
> これはどうですか?
> 少なくとも文法的には同じですよね。

気になりません。但し、それは呼び出し元が XmlDocument に xml を Load しているからであって、主語は呼び出し元だと思います。
上記理由から。呼び出し元が呼び出し先にむかって Get する際には何か取得できないと名前と動作が一致していません。
2007/08/06 21:56 | 囚人

# re: 主語は何か

主語は呼び出し元オブジェクトと考えても意味が通じることが多いですが、
それなら「I」や「The system」、「The Processor」や
「Current Thread」だったとしても意味が通じませんか?

そう考えると、
実は主語なんて存在してなくて、
メソッド名は行為の名称でしかない、
という結論にいたると思うのですが。
2007/08/06 22:56 | れい

# re: 主語は何か

> そう考えると、
> 実は主語なんて存在してなくて、
> メソッド名は行為の名称でしかない、
> という結論にいたると思うのですが。

それでも、メソッドには対象となるオブジェクトが存在します。
Get の対象となるオブジェクトが呼び出し元であったり、そうでなかったりすると混乱しませんか?
obj.Get~ だと obj から何か取得するであって、obj が何かを取得するという意味ではあってはならないと思うわけです。
2007/08/06 23:41 | 囚人

# re: 主語は何か

Get/Setはオブジェクトから取得する/に設定すると、
クラスライブラリでは統一しているようですから
.Netでは確かに違和感はありますねぇ。

他人が見るコードならなおさら、
わかりやすく名前付けしなければいけませんから、
.NetでGet/Setを使う場合は件のコードはダメっていうのは
正しいと思いますが。

なんて名前を付けたらいいのかわからなかったんじゃないかな。
きっと。
2007/08/08 1:13 | れい

# re: 主語は何か

> Get/Setはオブジェクトから取得する/に設定すると、
> クラスライブラリでは統一しているようですから
> .Netでは確かに違和感はありますねぇ。

いや、.NET どころかオブジェクト指向とかに限らず違和感はあります。

先で Win32 API を例に挙げているのでそれに倣いますと、GetSystemInfo() は呼び出し元がシステム情報を取得するという意味です。関数内でシステム情報を取得するという意味ではありません。

「関数が何をするか」という意味で関数名を決めるのではなく、「関数で何ができるか」という意味で関数名を決めるのが良い関数名だと思います。
GetHoge() という関数名にしておきながら、何も値を取得できない関数は混乱します。

ただ、C 言語の static な関数だとか、.NET や Java の private なメソッドだとかは、本文にも書いてあるように気持ちは分からなくもないですが。
2007/08/08 9:50 | 囚人

# QshtfPhZTvZGklgpzOK

Sent the first post, but it wasn`t published. I am writing the second. It's me, the African tourist.

# hgh releaser review

I like this blog very much so much excellent information.

コメントの投稿

タイトル
名前
URL
コメント