エンジニアのひよこ_level10

毎日更新してた人。たまに記事書きます。

【思考メモ】関数名をどうつける、クラスの分け方どうする【679日目】

思考メモ

なので、いい案あったらTwitterやコメントで教えてくださると嬉しいです(´;ω;`)

関数名には2種類ある?

public function showItemList($user_id)
{
    $user = $this->getUserByUserId($user_id);
    return $this->getUserItemList($user);
}

showItemListという関数名は、表示をさせたいという目的を指す関数。
getUserByUserIdという関数は、手段を指している関数。

抽象化された関数→具体的な手段の関数

ちょっと上の例良くないかもですが、

大まかにやりたい抽象化された概念の書かれた関数の中に、
具体的な手段を書いた関数を書くみたいなのはある気がしていますφ(・

知りたいこと

もし、この仮定があってるなら、この2つの関数にそれぞれ名前ってないですか。

あるいは、それぞれかき分けるにあたって、どんな層とかクラスに分ければいいですか

知っている方いらっしゃれば教えていただきたいですφ(・

【Laravel6】Laravel6で追加されるLazyCollectionに思いを馳せてみる【678日目】

現状一つ悩みがありました

リポジトリパターンと呼ばれる、永続化したデータを取得・操作する際に、
Repositoryクラスに集約させるようなやり方があるのですが、

Eloquentのchunkメソッドを使って取得するときに、取得中に別な作業をさせようとすると、
Repositoryクラス内に、永続化とは違う動きをさせてしまう・・・

かといって、クエリビルダをサービスに渡すと、データの取得方法がEloquent限定、
Serviceが意識しないといけなくなる・・・

class UserRepository
{
    function getUser()
    {
        return User::select('user.*');
    }
}
class UserService
{
....

    function getCsv()
    {
        $query = $this->user_repository->getUser();
        $query->chunk(100, function ($users) use ($csv) {
             foreach ($users as $user) {
                   $this->setCsvData($csv, $user);
             }
        });
    }
}

ってなことを、日本語PHPユーザーズのSlackのLaravelチャンネルで相談してたら、いい感じに盛り上がった・・・

ら、面白いものがLaravel6に出るようで

LazyCollection

注意) ここからは、コード動かしてない、内部のコード読んで推測しているだけのお話です。

どうやら、cursor関数で取得したときに、LazyCollectionというオブジェクトが返される模様。
foreachとかしてると、その度にクエリや該当取得方法が走るっぽいです。

github.com

ここで、クエリをLazyCollectionに内包させるっぽい?なるほどー!

何が嬉しい?

foreach ($lazy_collection as $user) { // Eloquentで生成したら、ここでクエリが走ってモデルclass取得
    いろんな処理
}

この時、$lazy_collectionを生成している方法がどのDBなのか、どんなクエリなのかは、このCollectionが持っています。
仮に取得方法が変わったとしても、このforeachを回すコードを書いた側は、
どんな取得方法なのかを考えずに、foreachを動かすことが出来ます。

ここで最初の悩みに戻りますが、これなら、ServiceにはとにかくLazyCollectionを渡してやれば、
Repositoryがどんな実装になろうが、差し替わろうが、Service側には影響がありません。

お、これなら最初の悩み解決しそうφ(・

感想: 楽しみ

感想!楽しみ!

ってことで、まだ使えないのですが、この時点で面白そうなのがわかりますね。

みなさんも、よかったらコード見てみませんか?面白いものが見れますよ?

参考コード

github.com

github.com

github.com

【Laravel】Eloquentでsaveを書くときに注意すべきこと(特に関数内で)【677日目】

Eloquent使って、saveがしたい!

function saveName(\App\Models\User $user)
{
    $user->name = "ringo";
    return $user->save();
}

このコード、怖い!!!
なぜか?

もし、$userにすでに別な値がセットされてたら?

public updateUser()
{
    $user = User::find(1);
    $user->age = 18;

    $this->saveName($user);
}

もしこんなコードだったら?

saveNameって関数で、 nameageの両方を保存してしまう。
このときの$userのsaveは、nameをringoにして、かつageを18にするコードになる。
意図しない動作になってしまう。

なんでだめだった?($userにセットされた値を全て保存)

saveというのは、『$userにセットされた値を全て保存』という認識のほうが近く、
saveNameの影響する範囲が、見た目よりずっと広いこと。

saveNameって書いているけど、実は『$userのnameのセット』と『$userにセットされた値を全て保存』の両方に責務がある

ではどうするか(関数の分け方)

setName(あるいはsetParam)とsaveで分けるべきでしたφ(・

テストコード書ける人は、ちょっとテストコードイメージすると、値が正しく保存しているかと、
セットされた値が保存できたかの2つに分かれるのがイメージできると思いますφ(・

【プログラミング】関数の切り分け・命名を大切にする利点とは?【676日目】

関数命名や関数切り出しって本当に大切?

プログラミングで、関数に切り出そうとか、関数名ちゃんと決めようとか言われることがあると思います。

でも、それって本当に大切?
綺麗なコード、見やすいコードって自己満足じゃないの?

そう思う時があると思います。

では、本当に利点があるのか。

その時点だと利点はない。後のみんなの幸せ

動作が変わらないので、その時点では確かに意味がないかもしれません。

ですが、『1年以上メンテナンスするコード』や『1000行超えるコード』であれば、話が大きく変わります。

1. 後にコードを読む人の速度が上がる
2. 読まなくていいコードを読まずに済む
3. バグを出すコードが作りにくくなる

等々、、、いろいろ利点があります。
実例を交えて、説明してみましょう。

例) 後の開発速度について

function updateUserRanking()
{
    $latest_user_ranking = $this->getLatestUserRanking();
    $this->setUserRanking($latest_user_ranking);
    $this->sendUpdatedNotificationMail();
}

■仕様変更
最新データの取得方法、AWSのs3からじゃなくて、自社サーバーのapiに変更になりました

さあ、このコードのどこを追えば良いでしょうか。

getLatestUserRankingを見ればいいのがすぐにわかりますね。

すぐわかると嬉しいのは?

では、これが1万行のコードだったら・・・どこ見ればいいかわからない。コードを追うだけでどれくらいの時間が失われるでしょう。

このコードは、少なくとも $this->setUserRanking($latest_user_ranking);と、 $this->sendUpdatedNotificationMail();を 見なくて良いのがわかります。
もし、行数が均等なら、約7000行のコードを読まなくても良くなりました。

1. 後にコードを読む人の速度が上がる
2. 読まなくていいコードを読まずに済む

この利点です。少なくとも、コードを読む時間はすっごく省略出来ます。

例) バグの出にくいコード

ここは、かなり語弊が生まれるかもしれませんが、あえてこう表現します。

function updateUserRanking()
{
    $latest_user_ranking = $this->getLatestUserRanking();
    $this->setUserRanking($latest_user_ranking);
    $this->sendUpdatedNotificationMail();
}

このコードで $this->getLatestUserRanking();の編集をしたとします。

これ、よっぽど変なコードを書かなければ $this->sendUpdatedNotificationMail();に影響はありません。

他のコードに影響がないことがわかりやすいのは、影響範囲をより小さく予測することが出来るようになります。
仮にバグったとしても、その周辺を見れば良いのがわかるでしょう。

順序を意味の単位でまとめられる

$a = 4;
$b = 5;
$d = $a + $b;
$e = $d + $a;

$x = $c + $d + $e;

$this->sendEmail();

このコードは、以下のように書き換えられます。

$a = 4;
$b = 5;
$d = $a + $b;

$this->sendEmail();
$e = $d + $a;

$x = $c + $d + $e;
$a = 4;
$b = 5;

$d = $a + $b;
$e = $d + $a;
$this->sendEmail();

$x = $c + $d + $e;

そう、 sendEmailの順番どうでもいいんです。
『今意識する必要ない』変数について、別な処理の途中に無駄に書いたり、絡まり合ったりするのは、非常に見にくくなります・・・

$x = $this->some_func($a, $b);

$this->sendEmail();

一気に見やすくなるし、各コードの影響範囲がわかりやすくなります。
関数に切り出す時点で、意味の単位で切り分けるようになるので、無駄なコードの絡まり合いが防げるようになります。

自分が『嫌だった』ことを覚えて、コードを綺麗にしてみよう

ここまで、『嫌なコード』をまとめていきましたが、
日常のプログラミングで、『ちょっとつらいな』って思うコードはあると思います。

ではどうしたら良いだろう?を考えて、綺麗に書くことを意識すると、
今は良いのを実感出来ないかもしれませんが、後の自分や他者の効率化に繋がります。

開発速度・バグなどに関わる関数化・命名について、今一度考えてみてはいかがでしょうか。

【Laravel】DBに保存時に、空文字""をnullに変換したいとき【675日目】

DBの保存に一手間追加したい

フォームの入力などで取得したデータを、ちょっと変形させてからDBに保存したい。

でも、コードの途中を変更することは困難だったり(オレオレフレームワークとか)、
該当カラムは必ず変形させたいとかがあったとします。

私だと、日付を入れるカラムに、空文字が来たらnullにしたい場合がありました。
Carbonに矯正されると‘0000-00-00’になってしまうので。

これらにどう対応するか

setXxxxAttributeの使い所

    public function setXxxxDateAttribute($value)
    {
        $this->attributes['xxxx_date'] = empty($value) ? null : Carbon::parse($value);
    }

Modelクラス上で、setXxxxAttributeを使いましょうφ(・

使い方を知っていても、使い時知ってないと忘れますねφ(・

参考

readouble.com

【一週間振り返り】ゆっくり過ごしてます\(^o^)/【674日目】

1.今週一週間の感想(ざっくり)

ゆっくり過ごしてます(‘ω‘ )

2.良かったこと

  1. イクラ遊んでました!
  2. ボードゲームカフェにも行きました!
  3. FGO(スマホゲーム)始めました!
  4. 家の近くのお店で、良いお店見つけました!

3.もっとこうしたかったこと

相手の気持ちを考えるって難しい(´・ω・`)

そしてそのためにやることの手がかりすらない(´・ω・`)

4.新しく気づいたこと

今週、落ち込んでも立ち直るスピード早かった。

これが心の余裕・・・?

5.来週したいこと

ぺちこんあと一ヶ月なのに何も用意してない\(^o^)/

あ、まだ休みます。再来週も夏休みもらってゆっくり休みます。

6.その他

とにかくやすも。そして色んな人頼ろう\(^o^)/

7.体重

100.6kg

いろいろ食べてるわりにはそんな増えてない?

Bootstrap4で中央に配置する方法【673日目】

Bootstrap3の場合

クラスの書き方が違います。こちらを参照どうぞ。

www.nyamucoro.com

結論

classにoffset-md-3で空白を作り、その後に目的の col-md-6などを配置する

公式ドキュメント

getbootstrap.com

正しくはブランク配置

Bootstrapは12カラムでブロックを配置しています。

クラスにoffset-md-3とか書くと、左に3カラム分空白が出来ます。

つまり、offset-md-3 col-md-6 なら
3 6 3となって中央に。
offset-md-4 col-md-4 なら
4 4 4となって中央になる。

結果的に中央になります。

【LogRocket】サイト閲覧者の行動を動画で見れることによる用途・感想【672日目】

LogRocketって?

www.nyamucoro.com

こちらに導入に関して書きました。

scriptタグ一つで、ユーザーの行動が動画見れるようになるツールです。

動画どんな感じ?

f:id:willow710kut:20190816201116g:plain

こんな風に、サイトにアクセスした人の動画が見れます。

1. エラーの原因がわかる

これは本来の用途で、エラーが起こった時のユーザーの行動がわかります。

通常のログだと、最後にアクセスしたタイミングの行動で判断しなければならず、
ログだけで特定できないバグは解決が困難です。

ですが、直前のアクションがわかれば、エラーの特定がさらにしやすくなる。便利ですねφ(・

ユーザーのアクションがわかる

マウスの動き・クリックもわかるので、『あ、この人コピペしたんだな』って。

今回用意したGifだと、わかりやすいです。

コピーするものによっては、コード以外のところをコピーする人もいるかもしれませんφ(・

ユーザーの関心がわかる

ユーザーがどこでマウスを止めた、どこまでスクロールしたかがわかります。

私みたいに記事を書いている人なら、どういった部分は読み飛ばされて、
どういった章を書けば、ユーザーは読むかを推測し、記事の構成の参考にすることが出来ますφ(・

とりあえず入れてみよう!

わりといろいろ学びがあるので、とりあえず入れてみるのがおすすめです!

あ、企業とかだと、クッキーポリシーとかちゃんと気をつけてくださいφ(・・私もこっそり書くようにしてます