
この間、とある初心者プログラマーから質問を受けました。
「なんでsetterやgetterを使うんですか?」
どうやらネットで調べても、意味のわからないコードを並べられて、よく意味が理解できないのだそうです。
何も不思議に思わずにコードを書いているベテランエンジニアに聞いても「そういうモンだから」としか返答が来なかったという憤りもあったようです。
オブジェクト思考と、classのモデル設計が強くなれるポイントなので、できるだけ簡単に説明してみたいと思います。
SetterとGetterの意味
いろいろな言語で、classが使えるようになって、
大体次のようなコードで説明されていることが多い。
# Javascriptの場合
class User{
#name = null
constructor(name){
this.name = name
}
getName(){
return this.name
}
setName(name){
this.name = name
}
}
# PHPの場合
class User{
private $name;
function __construct($name=null){
$this->name = name;
}
public function getName(){
reutrn $this->namel
}
public function setName($name=null){
$this->name = $name;
}
}
なんだか、name値ひとつで、ごっついプログラムを書いて、なんだかややこしいな〜と思いません?
初心者プログラマーの人はこの手順がどうやら面倒くさいと感じるようです。
熟練プログラマーの人であれば、多少の書き方の違いはあっても「こういうモノだ」と感じると思います。
Privateじゃなくて、Publicじゃダメなの?
PHPは、javaや他の言語のclassの書き方に似ているのでわかりやすいですが、
javascriptのprivateのclass変数プロパティは、#プレフィックスを、変数の先頭に付けることで、セットできます。
privateは、そのclassの内部からでしかアクセスできない変数や関数という意味で、外からのアクセスができなくなるので、
セキュアなプログラムが書けるとして、不具合を防ぐ安全なプログラムとして書かれます。
でも、setやgetで読み書きできるのであれば、いっそのこと、「class外からアクセスできる、publicにしてセットした方がいいんじゃね?」と考える人もいるようです。
「しかも、setもgetも、public設定なので、意味無いんじゃ無い?」とも言っています。
要するに次のように書く方が効率的じゃないかという事らしいです。
# Javascriptの場合
class User{
name = null
constructor(name){
this.name = name
}
}
# PHPの場合
class User{
private $name;
function __construct($name=null){
$this->name = name;
}
}
確かにシンプルなプログラムですね。
しかも、classをインスタンス化した後で、次のようにnameの書き換えができます。
# Javascriptの場合
const user = new User("ほげ太郎");
console.log(user.name) // -> ほげ太郎
user.name = "ほげの助"
console.log(user.name) // -> ほげの助
# PHPの場合
$user = new User("ふが太郎);
echo $user->name; // -> ふが太郎
$user->name = "ふがの助";
echo $user->name; // -> ふがの助
確かにシンプルですが、publicにすると、どんな値でも登録できてしまいます。
javascriptもPHPも変数の型にうるさく無い言語なので、nullでも、数値でも、文字列でも、オブジェクトでも何でも登録できてしまうので、
間違って登録されても、気が付かない状態になります。
setterとgetterを使うわけ
privateで、変数をセットするのは、型だけじゃなく、
登録したい値のバリデーションをセットできるからです。
バリデーションとは、
その値が正常にセットされるべき状態かどうかを担保する事です。
publicだと好き放題変数を上書きされて、バリデーションチェックがまるでできない状態ですが、
setterの関数内で、if文や、正規表現、独自の数式を使って、登録できない場合は、登録しなければいいだけで、
returnが必要であれば、trueやfalseを返してあげることで、安心安全なプログラムが構築できるようになります。
そして、getterでは、登録されている値を複数組み合わせたり、返すべき値に整形したり、計算して返す事で、
確実に設計通りの値が提供できるようになります。
でも、残念な感じなのは、設計がしっかりしていない値の扱いの場合は、「publicでええやん」となりがちなので、
privateで設定できていないプログラムに出会った時は、設計がイケていないという見方もできますね。
お作法による将来への備え
プログラム言語は、時折、バージョンアップという仕様変更に近い事が行われます。
プログラム言語のバージョンアップは、言語の機能向上の為に行われる事が大半ですが、
その中で、過去に使えていた機能を無くしてしまったり、
独自関数の使い方が変わったりしてしまう場合もあります。
Pythonのver2 -> ver3の変更は、かなりのインパクトが大きく、プログラマーを混乱させていまだに、2系、3系として、
現場で判断するフェイズもよく見かけます。
PHPでは、5系(具体的には、5.4と5.5)で大きな変革があり、下位互換と上位互換が大きく切り替えられたタイミングでもあります。
仕事などで、その言語の古いバージョンを使っていると、上位バージョンに切り替える、
アップグレード対応をすることになりますが、
この時に、今回説明した、setterやgetterなどのお作法が整っていると、修正作業もやりやすいのですが、
整っていないと、
一から作り直した方が早いという判断をするハメになりかねません。
あとがき
自分が今書いているプログラムを熟練プログラマーが見た時に、「もっとこうすればいい」というアドバイスをもらうことは、
プログラミングスキルの大きなアップデートになるんですが、
その内容が理解できないと、単に混乱するだけになる場合もあります。
ネットで調べても、セミナーで話を聞いても、職場ですぐ隣にいる熟練プログラマーに聞いても、自分が納得する返答が得られない事も多々あるのは、
初心者プログラマーのスキルが足りていないのではなく、熟練プログラマーは、説明が上手な人ばかりではないという事です。
実際今回のこのブログも、難しすぎてついていけないという人も多いので、ペルソナの目線に合わせるというアウトプットは重要なのです。
1対1での質疑応答であれば、目線合わせしやすいが、メディアアプトプットだと、一定のレベルの人をペルソナ定義してしまうので、なかなか難しいというのも事実です。(いいわけじゃないですが)
まあ、「わからなければ、身近にいる人に聞け!」という事です。
なんなら、ChatGPTに聞くのも今時ですよね。
0 件のコメント:
コメントを投稿