RAKUS Developers Blog | ラクス エンジニアブログ

株式会社ラクスのITエンジニアによる技術ブログです。

【オフショア】ベトナムメンバと理解する「PHPリーダブルコード」 〜第1回 表面的な改善〜

【オフショア】ベトナムメンバと理解する「PHPリーダブルコード」 〜第1回 表面的な改善〜

本稿では、ベトナムとのオフショア開発において利用できるよう、"リーダブルコード" の内容をもとに筆者が解釈したものを、社内用資料として日本語とベトナム語の両方で解説したものです。*1 この記事を日本チームとベトナムチームのメンバに読んでもらうことで、"リーダブルコード" の知識がチーム間の共通認識となり、プログラムコードの品質が向上することを目的としています。

全2回を予定しており、第1回である本稿は、「表面上の改善」について解説します。

Trong bài post này, tôi sẽ tóm tắt nội dung của "Readable code" và giải thích bằng cả tiếng Nhật và tiếng Việt, để có thể sử dụng trong việc phát triển Offshore với Việt Nam. Khi team Nhật Bản và team Việt Nam đọc bài viết này, sẽ có cách hiểu chung về kiến ​​thức "Readable code" giữa các team và hướng tới mục đích là để nâng cao chất lượng program.

Dự định tổng cộng là có 3 chương, và bài post này là Chương 1, giải thích về "Cải thiện về mặt hình thức".

記事一覧

  • 第1回 表面的な改善 / Cải thiện về mặt hình thức
  • 第2回 ロジックの単純化 / Đơn giản hóa Loop and Logic(未公開)

INDEX

ベトナムメンバと理解する「PHPリーダブルコード」
〜第1回 表面的な改善〜

PHP Readable code」hiểu được cùng với member Việt Nam
〜Chương 1 Cải thiện về hình thức〜

はじめに /
Lời nói đầu

Y-Kanoh は、ここ3年ほどベトナムにあるラクスの子会社 RAKUS Vietnam とのオフショア開発に携わっています。

私が所属しているチームでは、国内での開発ももちろん行いますが、要件が固まった後の設計から実装、テストまでベトナムのチームへ依頼することが多く、サービス開発にとって欠かせない存在です。 また、我々のチームでは、オフショア開発でよく言われれる言語や文化の違いによる認識齟齬や、大きな品質低下は少なく、むしろ一部のメンバは日本のメンバよりシステムの理解が深い場合もあるほどです。

しかしながら、この数年でいくつか課題も見えてきました。 その一つが「コード品質」です。

Tôi là Y-Kanoh đã tham gia vào Offshore development với Việt Nam tại Rakus trong khoảng 3 năm qua.

RAKUS Vietnam

Tất nhiên là tôi cũng phát triển trong nước (tại Nhật) với team mà tôi đang trực thuộc, nhưng chúng tôi thường nhờ Team Việt Nam từ phase thiết kế sau khi đã xác định yêu cầu đến implement và test, và việc phát triển ở Việt Nam đối với phát triển service là sự tồn tại không thể thiếu. Ngoài ra, trong team của chúng tôi, có rất ít mâu thuẫn về cách hiểu hay sự suy giảm chất lượng lớn bởi sự khác biệt về ngôn ngữ và văn hóa mà thường được cho là vì Offshore development, ngược lại còn có một số member có thể hiểu sâu về hệ thống hơn các member Nhật Bản ...

Tuy nhiên, trong vài năm gần đây, chúng tôi cũng nhìn thấy một vài vấn đề. Một trong số đó là "chất lượng code".

コード品質の問題点 /
Điểm vấn đề về chất lượng code

ラクスのベトナムメンバは品質に関する意識がとても高く、バグを含まないコードを作成していただけてはいるのですが、コードの "保守性" については日本との認識の違いを感じる場面があります。 これは、大きく以下の2点に問題があると考えています。

Các member Việt Nam của Rakus có ý thức rất cao về chất lượng, và đã có thể tạo ra code không có bug, nhưng về "tính bảo trì" của code, đôi khi tôi cảm thấy có sự khác biệt trong cách hiểu với Nhật Bản. Tôi nghĩ rằng điều này có 2 vấn đề chính sau đây.

一つ目は、日本からフィードバックがしづらいという点です。 弊社では、ベトナムチームとのコミュニケーションを通訳の方を介することで行っています。通訳の方々にはいつもスピーディに翻訳をしていただいていますが、日本からコードの修正を依頼する場合、【修正を依頼 → 翻訳作業 → ベトナムメンバによる修正 → 翻訳作業 → 修正結果を日本へ提出】 と、時間的なコストがかかってしまうため、修正依頼を躊躇してしまうことあります。(スケジュールに余裕がないときは特に...) 仕様通りにコードは動いているのでバグは生じていませんが、フィードバックを行わなければ、ベトナムメンバにどのようなコードが保守性が高く、読みやすいのかを伝える機会が減ってしまいます。

また、日本での実装時にはベテランの開発者が画面を指し示し、時には実装者の隣でコードを書きながら「良いコードとはなにか」を伝えることができますが、遠隔地であるベトナムのメンバとはそれができません。同じオフィスで働いていれば、こまめに声かけをして悩んでいる部分にアドバイスを出しながら実装を進めることができますが、ベトナムでの開発時は、遠隔地ゆえに詳しい状況がわからず、コードの実装やテストが終わって日本へ成果物が送られてきた時には、すでに良くない書き方で全てのコードが出来上がった状態であり、修正を依頼するには遅すぎる状態になってしまいます。

Đầu tiên là rất khó để đưa ra Feedback từ phía Nhật. Tại công ty chúng tôi, việc giao tiếp với team Việt Nam được thực hiện thông qua phiên dịch viên. Phiên dịch viên luôn dịch nhanh chóng cho chúng tôi, nhưng khi có yêu cầu chỉnh sửa từ phía Nhật, nếu [Yêu cầu chỉnh sửa → Thực hiện dịch → Member Việt Nam chỉnh sửa → Thực hiện dịch → Gửi kết quả chỉnh sửa cho phía Nhật], thì sẽ làm tốn cost về mặt thời gian, vì vậy đôi khi bị ngại yêu cầu chỉnh sửa. (Đặc biệt là khi schedule không cho phép...) Vì code vẫn đang hoạt động đúng theo specification nên không xảy ra bug, nhưng mà nếu không thực hiện feedback, sẽ làm giảm cơ hội nói cho member Việt Nam biết code như thế nào là có tính bảo trì cao và dễ đọc.

Ngoài ra, khi implement ở phía Nhật, các developer kỳ cựu có thể vừa chỉ vào màn hình và đôi khi ở bên cạnh implementer, vừa viết code vừa chỉ cho biết “thế nào là good code”, nhưng đối với member Việt Nam nơi xa xôi, thì không thể làm điều đó. Nếu làm cùng văn phòng, có thể thường xuyên gọi nhau, vừa đưa ra advice cho phần đang lo lắng, vừa tiến hành implement, nhưng khi phát triển ở Việt Nam, thì không biết tình hình chi tiết vì xa xôi, khi implement hay test code xong và thành phẩm được gửi cho phía Nhật, thì sẽ ở trạng thái tất cả các code đã được hoàn thành theo cách viết không tốt và sẽ quá muộn để yêu cầu chỉnh sửa.

二つ目の理由は、ベトナムにおける学習のしづらさです。 以前、私がベトナムに行った時、現地のメンバは学習に英語の書籍を使っていると聞きました。 ベトナムでは日本のように技術書が翻訳されて販売されていることがまだ少なく、開発者のスキルアップのためには英語での学習が必須だそうです。

私は英語が全く読めないので、私が英語でのみの学習をしなければいけない状態になったとしたら、スキルの上達はほぼ見込めなくなると思います 笑

ベトナムのメンバは少なくとも私より英語が得意ですが、やはり母国語でない言語での学習は負荷が高いのではないのでしょうか。

Lý do thứ hai là khó khăn trong việc học ở Việt Nam. Trước đây, khi tôi sang Việt Nam, tôi có nghe nói rằng các member ở đây sử dụng sách tiếng Anh để học. Ở Việt Nam, sách kỹ thuật mà được dịch và bán như ở Nhật Bản vẫn rất ít, để nâng cao kỹ năng của các developer dường như là bắt buộc phải học bằng tiếng Anh.

Tôi thì hoàn toàn không thể đọc tiếng Anh, vì vậy nếu tôi chỉ học bằng tiếng Anh, thì tôi nghĩ là gần như không thể mong đợi nâng cao được kỹ năng của mình (lol)

Các Member Việt Nam ít nhất cũng giỏi tiếng Anh hơn tôi, nhưng việc học bằng ngôn ngữ không phải tiếng mẹ đẻ có thể là một gánh nặng không phải sao.

コード品質向上を目指して /
Hướng tới mục đích nâng cao chất lượng code

これらの問題を解決するために、日本からのフィードバックがやりやすくなり、かつベトナムメンバが簡単に習得できるよう、有名な書籍「リーダブルコード」の内容をまとめ、ベトナム語に翻訳し、ベトナムチームに共有することにしました。

せっかくまとめるのであれば、ブログで公開することで他のオフショア開発を行なっているチームにも活用してもらえるかもしれないとの思いから、本記事を書くにいたります。

また、ラクスのブログで公開するにあたり、サンプルコードは我々の強みでもあるPHPで記載することにしました!

翻訳した文章も載せると、ブログの本文がかなりの文字量になってしまいます。そのため書籍の内容を3回に分けて解説します。

Để phía Nhật dễ feedback hơn và các member Việt Nam có thể học một cách dễ dàng, chúng tôi đã tổng hợp nội dung của cuốn sách nổi tiếng “Readable Code”, dịch sang tiếng Việt và chia sẻ cho team Việt Nam.

Nếu đã cất công tổng hợp, thì tôi sẽ viết bài này và xuất bản trên blog, vì tôi nghĩ rằng các team đang phát triển offshore khác cũng có thể sử dụng được.

Ngoài ra, tôi đã quyết định là khi xuất bản trên blog của Rakus, sẽ viết sample code bằng PHP là thế mạnh của chúng tôi!

Nếu post cả văn bản đã dịch, thì văn bản của blog sẽ có một lượng ký tự khá lớn. Vì vậy, tôi sẽ chia nội dung của cuốn sách làm 3 phần để giải thích.

この記事の使い方 /
Cách sử dụng bài viết này

チーム内の共通言語として /
Dưới dạng là ngôn ngữ chung trong team

  • 各テクニックを日本語とベトナム語の両方で記述しています
  • 各テクニックには、英語での名称をつけています
    • 日本もベトナムも使える英語のテクニック名があることで、フィードバック時に指し示しやすくなります
    • 英語名は原著をもとに、簡易な単語を利用しています
  • フィードバックや議論時に、この記事のリンクを貼るとさらに伝わりやすくなります

  • Mô tả từng technique bằng cả tiếng Nhật và tiếng Việt

  • Từng technique sẽ có đặt tên bằng tiếng Anh
    • Khi có technique name tiếng Anh mà phía Nhật và Việt Nam đều có thể sử dụng, thì sẽ dễ dàng chỉ ra hơn khi feedback
    • Tên tiếng anh sẽ dựa trên bản gốc và sử dụng từ đơn giản
  • Khi feedback hoặc thảo luận, nếu gắn link của bài viết này thì sẽ dễ truyền đạt hơn

Sample 1:

[Japanese]

ここの関数名は分かりづらいです。「2-2. Specific Words」を意識しましょう

[Vietnamese]

Tên hàm ở đây bị khó hiểu. Hãy lưu ý「2-2. Specific Words」

https://tech-blog.rakus.co.jp/entry/20220201/ReadableCodeWithVietnam01#2-2-Specific-Words

Sample 2:

[Japanese]

この定数は何を示しているのかコメントを残して欲しいです。

詳しくはこちらの「3-3. Add Comment on Constants」を参照してください。

[Vietnamese]

Tôi muốn là để lại comment rằng constant này chỉ điều gì.

Về nội dung chi tiết thì hãy tham khảo「3-3. Add Comment on Constants」ở đây

https://tech-blog.rakus.co.jp/entry/20220201/ReadableCodeWithVietnam01#3-3-Add-Comment-on-Constants

ベトナムでの学習資料として /
Dưới dạng tài liệu học ở Việt Nam

  • ベトナム語に翻訳しているため、ベトナムの方でも読みやすいはずです
  • プロジェクトに参画したベトナムメンバの学習資料として利用できます

  • Vì có dịch sang tiếng Việt nên chắc là đối với người Việt cũng sẽ dễ đọc

  • Có thể sử dụng làm tài liệu học cho member Việt Nam tham gia vào project

リーダブルコードについて /
Về readable code

www.oreilly.co.jp

The Art of Readable Code

リーダブルコード より良いコードを書くためのシンプルで実践的なテクニック

有名なより良いコードを書くためのテクニックがまとめられた書籍です。上記の通り、日本語の翻訳本があります。

この記事では、この"リーダブルコード"の内容を、解釈してベトナム語に翻訳しています。

Readable Code là Technique đơn giản và mang tính thực tiễn để viết code tốt hơn

Đây là cuốn sách nổi tiếng và tổng hợp technique để viết code tốt hơn. Như đã nói ở trên là có bản dịch tiếng Nhật.

Trong bài viết này, tôi sẽ tổng hợp, điều chỉnh nội dung “readable code” này và dịch sang tiếng Việt.

それでは、さっそくいきましょう!!

Vậy thì, cùng bắt đầu ngay thôi nào!!

1. "見た目" を整えるテクニック /
1. Techniques điều chỉnh "giao diện"

コードは"動けばいい"ものではありません。 コードを作成したのちに、保守運用を行うのは私たちです。そのためには、できるだけ他の編集者や未来の自分が読みやすいコードであることに気を配るべきです。

Code không phải "chỉ cần hoạt động là được". Sau khi viết code, chúng ta cần vận hành và bảo trì nó. Để làm được điều đó, cần phải lưu ý rằng phải là code càng dễ đọc càng tốt cho developer khác cũng như cho chính mình trong tương lai.

例えば、プログラムコードではなく、雑誌を想像してください。 雑誌では、読み手が読みやすく、重要なことはすぐ目に着くよう、余白や配置、情報のグルーピングに気を使って紙面が設計されています。

Ví dụ, hãy tưởng tượng là một tạp chí, chứ không phải program code. Trong tạp chí, trang giấy được thiết kế với sự chú ý đến margin, bố trí và grouping thông tin để người đọc dễ đọc và những điều quan trọng sẽ được chú ý ngay lập tức.

プログラムコードも同じで、次の開発者が誤解なくスピーディに修正が行えるよう、レイアウトには気を配るべきです。 まずはこの「コードの見た目」を整えるためのテクニックを紹介します。

Program code cũng vậy, cần phải chú ý bố cục để các developer tiếp theo không bị hiểu nhầm và có thể chỉnh sửa nhanh chóng. Trước hết, tôi sẽ giới thiệu technique để điều chỉnh "giao diện của code" này.

1-1. Consistent Line Breaks and Indents

  • 統一された改行とインデント
  • Ngắt dòng và thụt lề đã được thống nhất

#見た目 #インデント #改行 #統一感

以下のように、インデントがあっていないコードは読みづらくなってしまいます。 見やすくチームで決められたインデントをつけましょう。

Code không có thụt đầu dòng sẽ khó đọc, như dưới đây. Hãy thụt đầu dòng đã được quyết định theo nhóm cho dễ nhìn.

❌ Bad Code

<?php
class Task {
public $taskName;
public $status;
    private $user;
    private $deadline;
    
   public function __constractor(
         $name,
           $user)
   {
   $this->taskName = $name;
       $this->user = $user;
   }
}

同じように、改行位置も周りと合わせなければ読みづらくなってしまいます。 以下の場合、toManagerMail のみ改行位置がおかしいので、同じインスタンスが作成されていることに気づきにくくなっています。

Tương tự, nếu vị trí ngắt dòng cũng không phù hợp với xung quanh, thì sẽ rất khó đọc. Trong trường hợp sau đây, chỉ có toManagerMail có vị trí ngắt dòng bị kỳ cục, vì vậy rất khó để nhận thấy rằng instance tương tự đã được tạo.

❌ Bad Code

<?php
$toUserMail = new createMailObject(
    $subject,
    $toAddress,
    $fromAddress,
    $header,
    $body,
    $attach
);

$toCustomerMail = new createMailObject(
    $subject,
    $toAddress,
    $fromAddress,
    $header,
    $body,
    $attach
);

$toManagerMail =
    new createMailObject(  // Tại sao chỉ có ngắt dòng ở đây?? なぜここだけ改行されてる?? 
        $subject,
        $toAddress,
        $fromAddress,
        $header,
        $body,
        $attach
    );

1-2. Grouping of Code

  • コードのグループ化
  • Code grouping

#見た目

コードを読む時、コードが意味のある「グループ」にわかれていると読みやすいです。 文章や報告書を作成する時、内容によって段落を分けたり改行を入れたりすることと一緒です。

Khi đọc code, sẽ dễ đọc hơn nếu code được chia thành các "group" có ý nghĩa. Nó cũng giống như việc khi tạo một câu văn hay báo cáo, phải tách đoạn văn và ngắt dòng tùy theo nội dung.

❌ Bad Code

<?php
function suggestNeverUseRecipes($userId)
{
  // Lấy recipe (công thức) mà user đã từng tạo và so sánh với recipe đã đăng ký
  // Sau đó, hiển thị recipe mà chưa từng làm
  // ユーザが作ったことがあるレシピを取得し、登録されているレシピと比べる
  // その後、まだ作ったことないレシピを表示する
  $user = new User($userId);
  $recipeList = $user->getMadeRecipeList();
  $recipeBook = new RecipeBook();
  $allRecipeList = $recipeBook->getAllRecipeList();
  $suggestRecipeList = array_diff_key($allRecipeList, $recipeList);
  $display["user"] = $user;
  $display["suggestRecipeList"] = $suggestRecipeList;
  return render("sugestRecipe.html", $display);
}

✅ Good Code

<?php
function suggestNeverUseRecipes($userId)
{
  // Lấy recipe mà user đã từng tạo
  // ユーザが作ったことがあるレシピを取得
  $user = new User($userId);
  $recipeList = $user->getMadeRecipeList();
  
  // Lấy tất cả các recipe
  // 全てのレシピを取得
  $recipeBook = new RecipeBook();
  $allRecipeList = $recipeBook->getAllRecipeList();
  $suggestRecipeList = array_diff_key($allRecipeList, $recipeList);
  
  // Xử lý hiển thị màn hình
  // 画面表示処理
  $display["user"] = $user;
  $display["suggestRecipeList"] = $suggestRecipeList;
  
  return render("sugestRecipe.html", $display);
}

書いてあるコードが一緒ですが、グルーピングをすることで理解しやすくなりました。 また、グループごとにコメントを入れると、さらにわかりやすくなります。

Code được viết là giống nhau, nhưng nó sẽ trở nên dễ hiểu hơn khi grouping lại. Ngoài ra, nếu thêm comment cho từng group thì sẽ dễ hiểu hơn nữa.

1-3. Meaningful Order

  • 意味のある順番を選ぶ
  • Chọn thứ tự có ý nghĩa

#見た目 #順番

ロジックに影響を与えなくても、コードを記載する順番は揃えた方がいいでしょう。 いくつかのデータを同じ処理で処理する場合、場所によって順番が違うと、理解の妨げになります。 以下の例では、$mailaddress がどこにあるのか不思議に思った時点で、脳のリソースが余計なことに使われてしまっています。

Ngay cả khi không ảnh hưởng đến logic, cũng nên canh chỉnh thứ tự mô tả code sẽ tốt hơn không phải sao? Khi xử lý một số dữ liệu trong cùng một xử lý, nếu thứ tự khác nhau tùy vào vị trí, thì sẽ rất khó hiểu. Trong ví dụ dưới đây, khi phải thắc mắc, suy nghĩ xem $mailaddress nằm ở đâu, thì bạn đang sử dụng chất xám lãng phí.

❌ Bad Code

<?php
$userName = $request->("userName");
$mailaddress = $request->("mailaddress");
$phonNumber = $request->("phonNumber");
$zip = $request->("zip");
$location = $request->("location");

 :
 :
 :

if($userName === "") {
  $errorMessage[] = USER_NAME_EMPTY_ERROR;
}
if($phonNumber === "") {   // Ủa? $mailaddress đâu? あれ? $mailaddress は? 
  $errorMessage[] = PHONE_NUMBER_EMPTY_ERROR;
}
if($zip === "") {
  $errorMessage[] = ZIP_EMPTY_ERROR;
}
if($location === "") {
  $errorMessage[] = LOCATION_EMPTY_ERROR;
}
if($mailaddress === "") {   // Thì ra là ở chỗ này !! こんなところにあった!!
  $errorMessage[] = MAILADDRESS_EMPTY_ERROR;
}

2. 命名のテクニック /
2. Naming technique

変数や関数、クラスなど、コード内に記載される "名前" は、"短いコメント" と考えるべきです。 しかし、名前をつけた本人は「わかりやすい」と思っている名前でも、他の人にとってはわかりづらい場合も多いのではないでしょうか。 そのため、常に他者にとって理解の助けになる名前になっているかを考えて名前をつける必要があります。

"Tên" được ghi trong code, chẳng hạn như biến, hàm và class, nên được coi là "comment ngắn". Tuy nhiên, cho dù nó là cái tên mà người đặt tên cho rằng nó "dễ hiểu" thì cũng có khi khó hiểu đối với người khác không phải sao? Vì vậy, cần phải luôn xem xét đặt tên xem liệu cái tên đó có giúp người khác hiểu được hay không.

2-1. Not Use Too Generic Names

  • 一般的すぎる単語を使わない
  • Không sử dụng từ ngữ quá chung chung

#命名 #英語

前述した通り、変数名/関数名は、ある種のコメントです。 いい名前がついていた場合、そのコードを読む人のヒントになります。 コードを書くときに命名を考えない場合、次回そのコードを読む人はヒントなしでコードを解読する羽目になります。 わざわざチームメンバや未来の自分にハードモードのステージを用意する必要はありません。

Như đã đề cập trước đó, tên biến/hàm là một loại comment. Nếu gắn một cái tên hay, thì nó sẽ là hint (gợi ý) cho người đọc code đó. Nếu không xem xét đến việc đặt tên khi viết code, người tiếp theo đọc code sẽ rơi vào tình thế đọc code mà không có gợi ý nào. Không cần phải mất công chuẩn bị một cái gì đó quá khó cho các member trong team hoặc chính mình trong tương lai.

以下のような単語は、命名をサボったようなものです。 あまりに抽象的で、なにをするための変数名、もしくは関数名なのかわかりません。 このような名前を使いそうになったら、もっと目的に適した具体的な名前があるはずなので、名前をしっかり考えましょう。

もし、どうしても使いたい場合は、スコープが短く、誰が見ても用途が明らかな場合にのみ使用するようにするべきです。

Những từ ngữ như sau đây giống như là lười biếng, tránh né đặt tên. Nó quá trừu tượng nên không biết tên biến hoặc hàm dùng để làm gì. Nếu có vẻ như bạn đang sử dụng một cái tên như vậy, thì chắc là cần có một cái tên cụ thể hơn cho mục đích đó, vì vậy hãy xem xét tên thật kỹ.

Nếu thực sự muốn sử dụng nó, thì chỉ nên sử dụng khi phạm vi ngắn và dù ai xem cũng hiểu rõ được công dụng.

❌ Bad Code

<?php
$tmp       // ... mang tính tạm thời, là cái gì?
           // 一時的な...なに??
$myForm    // Bằng với là không có thông tin “my form”
           // "私のフォーム" 情報が無いに等しい 
$retval    // Không có thông tin nào ngoài “Giá trị trả về”. Không cần đặt tên biến cũng biết
           // "戻り値"以外の情報がない。変数名にしなくてもわかる
$i, $j, $k // Loop iterator. Chắc là có một cái tên hay hơn 
           // ループのイテレータ。もっといい名前があるはず
$result    // Là kết quả của cái gì. Tôi muốn thêm một vài từ
           // なにかの結果。もう一言欲しい。

2-2. Specific Words

  • 明確な単語を選ぶ
  • Chọn từ rõ ràng

#命名

以下のような名前は簡単に思いつくので使いやすいですが、いまいち情報不足です。

Ví dụ như cái tên dưới đây vì rất dễ nghĩ ra trong đầu nên dễ sử dụng, nhưng mà không đủ thông tin lắm.

❌ Bad Code

<?php
function getPage(){...}
function setLog(){...}
function checkMailAddress(){...}

getsetは、明確に何を行うかがわかりづらくなります。 アクセサ(gettersetter)のように、特にルールがなく、もっと処理内容を表現できる単語がある場合は使用を避けるべきでしょう。

getset khiến bạn khó biết rõ là thực hiện cái gì. Nên tránh sử dụng nó khi không có rule nhất định, và khi có những từ có thể diễn đạt rõ nội dung xử lý hơn, chẳng hạn như Accessor(gettersetter

loadfetchような単語に置き換えてはどうでしょうか。単にget(取得する)だけではなく、どのように取得するのかが伝わりやすくなる単語です。

また、getsetは、「何か簡単な、負荷のかからない処理」であるイメージがあると思います。 一方でloadと聞くと、何か時間のかかる処理に聞こえませんか? 命名をするときには、その名前を見た他の開発者がどういう処理を想像するかを考えることも重要です。 (getって書いてあるから軽い気持ちで使っていたけど、すごく処理に時間がかかる処理だった!なんて事故を減らしましょう。)

Nếu thay thế thành từ như là load hay là fetch thì bạn thấy sao? Không chỉ đơn giản là get (lấy), mà là từ “lấy như thế nào” thì sẽ dễ hiểu hơn.

Ngoài ra, tôi nghĩ là getset làm cho có hình dung là”một xử lý gì đó đơn giản và nhẹ nhàng”. Mặt khác, khi nghe từ load, thì nghe có vẻ như là xử lý gì đó tốn thời gian không phải sao? Khi đặt tên, “việc mà xem xét làm sao cho các developer khác khi nhìn vào tên đó sẽ tưởng tượng ra xử lý như thế nào” cũng quan trọng. (Vì viết là get sẽ sử dụng với cảm giác nhẹ nhàng, nhưng nó là xử lý mất rất nhiều thời gian để xử lý!Nên hãy giảm thiểu sự cố.)

✅ Good Code

<?php
function downLoadPage(){...}
function registerLog(){...}
function isValidMailAddress(){...}

明確に意図が伝わらない例として、たとえば以下のような関数があったとします。 この関数は、filterの意味が曖昧なので、2つの意味で解釈できてしまいます。

Lấy ví dụ về việc ý định không được truyền đạt rõ ràng, tôi giả sử là có hàm sau đây. Hàm này có thể hiểu theo hai cách vì ý nghĩa của filter bị mơ hồ.

❌ Bad Code

<?php
function filterMailBySendDate($date){...}
  • 解釈1:メール送信日が$dateのメールを取得する
  • 解釈2:メール送信日が$dateのメールを除く

解釈1の場合、selectを使った方がいいかもしれません。 また、解釈2の場合は、excludeを使うことで明確になります。

  • Cách hiểu 1:Lấy mail có ngày gửi mail là $date
  • Cách hiểu 2:Loại trừ mail có ngày gửi mail là $date

Nếu là cách hiểu 1 thì có lẽ là nên sử dụng select Ngoài ra, nếu là cách hiểu 2, thì sử dụng exclude sẽ rõ ràng hơn.

✅ Good Code

<?php
function selectMailBySendDate($date){...}
function excludeMailBySendDate($date){...}

以下にもう少し意味が伝わりやすくなる単語の例をあげました。 もし、置き換えられる言葉があるのであれば、積極的に置き換えましょう。

Tôi đã nêu ra một số ví dụ về các từ giúp truyền đạt ý nghĩa dễ dàng hơn một chút ở dưới đây. Nếu có từ nào có thể thay thế, thì hãy tích cực thay thế nhé!

曖昧な単語 / Từ mơ hồ 明確な単語 / Từ rõ ràng
get, set load, fetch, register, add, store
send deliver, dispatch, announce, distribute, route
find search, extract, locate, recover
start launch, create, begin, open
make create, set up, build, generate, compose, add, new
check isValid, enable, isEmpty, isSaved, exist
filter select, exclude

2-3. Attaching Information to a Name

  • 名前への情報追加
  • Thêm thông tin vào tên

#命名

変数名には、できるだけ具体的な名前をつけることで、どのような意図で変数を使うかがわかりやすくなります。 それに加えて、なにか"絶対に伝えないといけない情報"があるのであれば、変数名に付け加えることで事故が少なくなります。

Khi đặt tên cho biến cụ thể hết mức có thể, thì sẽ dễ hiểu bạn định sử dụng biến để làm gì. Thêm vào đó, nếu có "thông tin bắt buộc phải truyền tải" nào đó, thì thêm nó vào tên biến sẽ giảm thiểu được sự cố.

🤷‍♂️ NOT Good Code

<?php
// Không tệ, nhưng nếu có thể bổ sung thêm thông tin thì nên mô tả
// 悪くはないが、もう少し情報を付け加えられるのであれば記載するべき
$password
$comment
$fileSize
$delay
$length
$html

✅ Good Code

<?php
$plaintextPassword  // Hiểu được rằng nó không được encrypte
                    // 暗号化されていないことがわかる
$escapedComment     // Hiểu được rằng nó đã được escape
                    // エスケープされていることがわかる
$fileSizeMb         // Hiểu được rằng nó là đơn vị MB
                    // MB単位であることがわかる
$delaySec           // Hiểu được rằng nó là đơn vị giây 
                    // 秒単位であることがわかる
$widthLength        // Hiểu được rằng nó là độ dài chiều ngang
                    // 横の長さであることがわかる
$htmlTextUtf8       // Hiểu được rằng nó là UTF-8
                    // UTF-8になっていることがわかる

$fileSizeMb のように、単位を変数に含めるテクニックはぜひやりたいところです。 コードを遡って、この変数に入っている数値の単位がなんなのか、探すのに時間がかかってイライラしたことはありません??

Tôi muốn nhất định phải thực hiện một technique bao gồm đơn vị trong biến, chẳng hạn như $ fileSizeMb. Bạn đã bao giờ cảm thấy bực bội vì “mất thời gian quay ngược lại code và tìm đơn vị của giá trị số trong biến này là gì” chưa ??

2-4. Not Use Abbreviations

  • 略語を使わない
  • Không sử dụng chữ viết tắt

#省略

具体的に、そしてわかりやすく名前を決めようとすると、どうしても長い名前になってしまいます。 しかし、名前を短くするために、意図が伝わらなくなってしまっては意味がありません。 短い名前の方が見やすくていいかもしれませんが、他の人に伝わる名前にすることを優先して考えましょう。

Nếu bạn định là quyết định một cái tên cụ thể và dễ hiểu, tự nhiên thành ra một cái tên dài. Tuy nhiên, vì rút ngắn tên mà không được truyền đạt được ý đồ thì sẽ không có ý nghĩa gì. Tên ngắn có thể dễ đọc hơn, nhưng hãy ưu tiên cái tên có thể truyền đạt cho người khác.

また、同じ理由で無理な略語も避けるべきです。 賛否両論あると思いますが、一般的な開発者なら理解できる uiddaostrenv のような単語であればまだ利用しても問題ないかもしれません。 ただし、チームに参画したばかりの開発者が読んでわからないようなシステム独自の略語は避けるべきです。 たとえば、以下のような名前です。

Ngoài ra, vì lý do tương tự, bạn cũng nên tránh những từ viết tắt không hợp lý. Tôi nghĩ là sẽ có 2 luồng ý kiến, nhưng có lẽ vẫn ổn khi sử dụng những từ như uid,dao, str, vàenv mà một developer bình thường có thể hiểu được. Tuy nhiên, bạn nên tránh các từ viết tắt của riêng hệ thống mà các developer mới join vào team đọc vào sẽ không hiểu được. Ví dụ, như là tên sau đây.

❌ Bad Code

<?php
$mBox       // Viết tắt của MailBox. Mới nhìn lần đầu sẽ không biết “m” là gì
            // MailBox の略。初見で"m"が何かわからない
$cUrl       // Viết tắt của ClickedUrl
            // ClickedUrl の略
$BEManager  // Viết tắt của BackEndManage
            // BackEndManage の略

どこまでの略語が許されて、どこからが許されないかの線引きは難しいと思います。 そのため、私は基本的に「迷ったら略語は利用しない」方針で名前を決めるべきだと考えています。

また、「変数名が長くて入力しづらい」と思うのであれば、略語を使う前にIDEの補完入力を覚えましょう。

Tôi nghĩ rất khó để vạch ra ranh giới giữa việc “được viết tắt đến đâu” và “chỗ nào là không được viết tắt”. Vì vậy, về cơ bản tôi nghĩ rằng nên quyết định tên theo phương châm "nếu phân vân thì không sử dụng chữ viết tắt".

Ngoài ra, nếu bạn nghĩ "tên biến dài và khó nhập", hãy nhớ việc IDE completion input (nhập hoàn thành của IDE) trước khi sử dụng các từ viết tắt.

2-5. Choice Easy Word

  • 簡単な単語を使う
  • Sử dụng các từ đơn giản

#命名 #英語 #単語

ここまで、具体的で明確な単語を使うことを述べてきました。 しかし、いくら具体的でも、難しすぎて意味が通じない単語を選んでは意味がありません。

線引きは難しいですが、必要以上に難しい単語を選ばないようにしましょう。

Đến đây, tôi đã mô tả xong việc sử dụng từ một cách rõ ràng và cụ thể. Tuy nhiên, cho dù cụ thể đến đâu, thì nếu chọn 1 từ quá khó không diễn đạt được ý nghĩa thì cũng không có ý nghĩa gì.

Rất khó để phân định ranh giới rõ ràng, nhưng hãy cố gắng không chọn những từ khó hơn mức cần thiết.

❌ Bad Code

<?php
$investigateRecipe
$manufactureBook

✅ Good Code

<?php
$searchRecipe
$createBook

3. コメントのテクニック /
3. Technique về comment

コメントは、そのコードを作成した人が残すことができる未来の開発者へのヒントです。 将来そのコードを修正する他者や自分のため、価値のある情報を記載しましょう!!

Comment là hint mà người viết code đó có thể để lại dành cho developer trong tương lai. Vì người khác hoặc chính mình sẽ chỉnh sửa code trong tương lai, hãy mô tả thông tin có giá trị !!

3-1. Comments at Correct Situation

  • 正しい状況でコメントを使う
  • Sử dụng comment với tình huống đúng

#コメント #コメント内容

コメントの目的は、"書き手の意図を読み手に伝えること" です。 そのため、以下のようなコメントは不要です。なぜなら、コードを読めばすぐに伝わるからです。

Mục đích của comment là "để truyền tải mục đích của người viết đến người đọc". Vì vậy, những comment như sau đây là không cần thiết. Bởi vì, nếu đọc code, thì sẽ hiểu ngay lập tức.

❌ Bad Code

<?php
// Lấy thông tin account
// アカウント情報を取得する
$account = new Account($id);

// Setting user name cho account
// アカウントにユーザ名を設定する
$account->setUserName($name);

// Xóa thông tin account
// アカウント情報を削除する
unset($account);

以下のように、短いコードでも読んですぐにわからないようなコードであれば、コメントをつけるべきです。

Nếu là code ngắn mà đọc vào không hiểu ngay lập tức được như dưới đây, thì nên thêm comment

✅ Good Code

<?php
// Biểu thức chính quy để kiểm tra xem số điện thoại có dấu gạch nối hay không
// ハイフン付きの電話番号であるかを確認する正規表現
$phoneNumberReg = "/^[0-9]{2,4}-[0-9]{2,4}-[0-9]{3,4}$/";

3-2. Recording Your Thoughts

  • 考えを記録する
  • Ghi lại suy nghĩ

#コメント #コメント内容

コードには処理内容を記述することはできますが、コードを書いていたときにあなたが考えていたことまでは記述できません。 そのコードを書いていたときに考えていた内容こそ、コメントに記載して後世に残すべきでしょう。

たとえば、以下のような内容です。

Bạn có thể mô tả nội dung xử lý cho code, nhưng khi viết code bạn không thể viết hết những gì bạn đang suy nghĩ. Những gì bạn đã nghĩ khi viết code nên được đưa vào comment và để lại cho thế hệ sau.

Ví dụ, nội dung như sau.

✅ Good Code 注釈としてのコメント / Comment như một chú thích

<?php
// Xử lý này có tốc độ xử lý nhanh hơn mô tả trong loop
// この処理はループで記述するより処理速度が速い

また、コードを記載しているうちに、そのコードを触るときに注意すべき点があれば、コメントに記載することで他の開発者が罠を踏むことはなくなります。

Ngoài ra, trong lúc viết code, nếu có điều gì cần phải lưu ý khi đụng vào code đó, thì bạn có thể viết nó trong comment để các developer khác không bị mắc bẫy.

✅ Good Code 罠の警告 / Cảnh báo bẫy

<?php
// Xử lý này có sai sót và không nên chỉ định mảng có chứa NULL trong phần tử làm đối số. Tại vì ….
// この処理には欠陥があり、要素にNULLを含む配列を引数に指定するべきではない。なぜなら...

// Lưu ý rằng xử lý sẽ mất thời gian nếu Nest của tag HTML bị sâu.
// HTMLタグのネストが深いと処理に時間がかかってしまうので注意

コードを理解するときに、全体像がわかっていると理解が速くなります。 そのため、コードの最初に以下のような全体像を把握できるコメントを書くべきです。

Khi hiểu code, nếu hiểu được bức tranh tổng thể thì sẽ hiểu nhanh hơn. Do đó, bạn nên viết comment ở đầu đoạn code để có thể nắm được bức tranh tổng thể như dưới đây.

✅ Good Code 全体像の共有 / Share về bức tranh tổng thể

<?php
// Class này là class trao đổi với service liên kết bên ngoài.
// このクラスは外部連携サービスとのやりとりを行うクラスです。

// Class này là code xử lý DB từ business logic. Không được phép gọi từ application.
// このクラスはビジネスロジックからDBを扱うコードです。アプリケーションから呼んではいけません

// Tạo mảng mà chỉ bao gồm user cần hiển thị
// 表示すべきユーザのみが含まれる配列を作成する

3-3. Add Comment on Constants

  • 定数にコメントをつける
  • Thêm comment vào constant

#コメント #コメント内容 #定数

いわゆる”マジックナンバ”は良くありません。なぜなら、その数値がなんのための数値かわからないからです。

Nói nôm na là “magic number” không được tốt lắm. Lý do là vì không biết được giá trị số đó là giá trị để làm gì.

❌ Bad Code

<?php
if($fileSizeMb < 20) {     // "20" là số gì? "20" ってなんの数字?
    return FILE_SIZE_ERROR;
}

しかし、このマジックナンバを定数にしたところで、あまり解決になっていません。

Tuy nhiên, khi set magic number này thành constant, thì nó vẫn chưa được giải quyết nhiều.

❌ Bad Code

<?php
const FILE_MAX_SIZE_MB = 20;

if($fileSizeMb < FILE_MAX_SIZE_MB) {
    return FILE_SIZE_ERROR;
}

たしかに、定数名(FILE_MAX_SIZE_MB)から"ファイルの最大サイズ"であることはわかりますが、なぜファイルの最大サイズが20MBなのかはわかりません。 仕様上決まっているのかもしれませんし、もしかしたらこのシステムではそれ以上のファイルを処理すると問題が発生するのかもしれません。

このような場合、マジックナンバを定数にするだけで満足せず、コメントを残すべきです。

Chắc chắn là có thể biết từ constant name (FILE_MAX_SIZE_MB) rằng đó là" size tối đa của file", nhưng không biết được size tối đa của file là 20MB. Có lẽ là đã quyết định trên specification, hoặc có thể sẽ xảy ra vấn đề khi xử lý file lớn hơn trong hệ thống này.

Trong những trường hợp như vậy, bạn không nên hài lòng với việc chỉ set magic number thành constant mà nên để lại comment.

✅ Good Code

<?php
// Size tối đa của file
// Nếu đăng ký file lớn hơn, thì sẽ không thể đính kèm vào mail thông báo để gửi cho user.
// ファイルの最大サイズ。
// これ以上のファイルを登録すると、ユーザへ送信する通知メールに添付できなくなってしまう。
const FILE_MAX_SIZE_MB = 20;

if($fileSizeMb < FILE_MAX_SIZE_MB) {
    return FILE_SIZE_ERROR;
}

3-4. Avoid Ambiguous Pronouns

  • 曖昧な代名詞を避ける
  • Tránh các đại từ không rõ ràng

#コメント #コメント内容

代名詞を使うと、意図を正確伝えづらくなります。 とくに我々は母国語が違うので、代名詞が何を指し示しているのか勘違いして理解することが他の開発現場よりとても多いでしょう。

そのため、代名詞はできるだけ使わず、直接的な表現を心がけましょう。

Nếu sử dụng đại từ thay thế sẽ khiến bạn khó truyền đạt ý định chính xác. Đặc biệt là vì chúng ta có ngôn ngữ mẹ đẻ khác nhau, nên sẽ có rất nhiều khả năng hiểu sai là “đại từ thay thế đang chỉ cái gì” hơn so với các nơi phát triển khác.

Do đó, hãy cố gắng sử dụng cách diễn đạt trực tiếp mà không sử dụng đại từ thay thế càng nhiều càng tốt.

日本のメンバは高校での英語の授業を思い出してください。 よくある「Q.下線部Aの"it"が指し示していることはなんですか?」という問題です。 わざわざ高校英語で出てくる読解問題をコメントに含める必要はありませんよね??

Các member phía Nhật hãy nhớ lại các buổi học tiếng Anh ở trường trung học. Là vấn đề thường gặp như là "Q."it" trong chỗ A được gạch dưới đang chỉ đến điều gì?". Không cần phải đưa các bài tập đọc hiểu xuất hiện trong tiếng Anh cấp 3 vào phần comment nhỉ ???

❌ Bad Code

<?php
// Cho data vào Cache. Trước đó, sẽ xác nhận size đó
// データをキャッシュに入れる。その前にそのサイズを確認する

✅ Good Code

<?php
// Cho data vào Cache. Trước đó, sẽ xác nhận size của data
// データをキャッシュに入れる。その前にデータのサイズを確認する

✅ More Good Code

<?php
// Sau khi xác nhận size của data thì cho data vào Cache 
// データのサイズを確認してから、データをキャッシュに入れる

余談ですが、私は普段の作業指示書作成時にも代名詞や指示語を使わないようにしています。 ただでさえたくさんの翻訳を依頼している翻訳チームのメンバを、これ以上困らせるわけにいかないので。。。

Tôi xin nói ngoài lề một chút là, cả khi tạo tài liệu chỉ thị công việc bình thường, tôi cũng cố gắng không sử dụng đại từ thay thế hoặc từ chỉ thị. Vì đã yêu cầu dịch rất nhiều rồi nên không thể làm cho các member của team phiên dịch khó khăn (khó dịch) hơn ....

3-5. Write Examples

  • 入出力の具体例を使う
  • Sử dụng ví dụ cụ thể của in/output

#コメント #コメント内容

無理に言葉を使って説明するより、具体例を書いた方がわかりやすいこともあります。 ましてや我々は母国語が違います。言葉で語らずコードで語った方がわかりやすい時もあります。

Đôi khi, việc viết ra một ví dụ cụ thể sẽ dễ hiểu hơn là cưỡng ép giải thích nó bằng lời. Hơn nữa, chúng ta có ngôn ngữ mẹ đẻ khác nhau. Đôi khi sẽ dễ hiểu hơn nếu nói bằng code thay vì bằng lời.

✅ Good Code

<?php
/*
 * Xóa các ký tự có trong $char ở đầu và cuối $targetStr
 * Sample: trimEachStr("abcabcba", "ab") trả về “cabc”
 *
 * $targetStr の先頭や末尾にある $char に含まれる文字を取り除く
 * Sample: trimEachStr("abcabcba", "ab") は "cabc" を返す
 * 
 **/
function trimEachStr($targetStr, $char) {...}

3-6. Named Arguments

  • 名前付き引数
  • Đối số có kèm tên

#PHP #コメント

PHP には PHP 8.0 の新機能として名前付き引数が採用されました!!

名前付き引数は、引数の位置を指定して引数のデフォルト値の利便性を高めるだけでなく、関数呼び出し元でのコメントとして使うことができます。

PHP đã áp dụng Đối số có kèm tên như một tính năng mới của PHP 8.0 !!

Đối số có kèm tên không chỉ có thể chỉ định vị trí đối số và nâng cao tính tiện lợi của giá trị mặc định của đối số, mà còn có thể sử dụng làm comment ở nơi gọi hàm.

❌ Bad Code

<?php
connect(10, false); // Không hiểu ý nghĩa của 10 và false
                    // 10 と false の意味がわからない
  :
  :
  :

// connect の定義元を確認して、やっと 10 と false の意味がわかる
// Xác nhận nguồn định nghĩa connect, cuối cùng cũng hiểu ý nghĩa của 10 và false
function connect($timeOutSec, $useEncryption) {...}

✅ Good Code

<?php
// Ngay cả khi không xác nhận nguồn định nghĩa connect cũng hiểu được ý nghĩa
// connect の定義元を確認しなくても意味がわかる
connect(timeOutSec:10, useEncryption:false);

  :
  :
  :

function connect($timeOutSec, $useEncryption) {...}

3-7. Use PHPDoc

  • PHPDocを利用する
  • Sử dụng PHPDoc

#コメント #PHPDoc #PHP

PHPは、変数の中にintegerもbooleanも、arrayもすべて入れることができてしまうため、期待していない型が変数に入ってしまうことも多々あります。

意図しない値が変数に含まれてしまう可能性を減らすためには、IDEとPHPDocを利用します。

PhpStormを使っている場合、関数の引数に、PHPDocで記載されている型と違う値が含まれていると警告を表示してくるなど、PHPDocを使って型指定のサポートを行う機能がたくさん含まれています。 そのため、PHPDocは正確に、漏れなく記載しましょう。

また、近年のPHPでは引数や戻り値の型を指定できるようになっています。できるだけ型を指定して、その後の修正によって意図しない値が利用されるリスクを減らしましょう。

PHP có thể đặt tất cả các integer, cả boolean, cả array trong các biến, nên thường xảy ra trường hợp “kiểu không mong muốn” được đưa vào các biến.

Sử dụng IDE và PHPDoc để giảm nguy cơ các giá trị không mong muốn được bao gồm trong biến.

Khi sử dụng PhpStorm, có rất nhiều chức năng sử dụng PHPDoc để support chỉ định kiểu, chẳng hạn như hiển thị cảnh báo nếu đối số của hàm chứa giá trị khác với kiểu được mô tả trong PHPDoc. Do đó, PHPDoc nên được viết chính xác và không thiếu sót.

Ngoài ra, trong những năm gần đây PHP đã có thể chỉ định đối số và kiểu giá trị trả về. Để giảm nguy cơ sử dụng các giá trị không mong muốn, hãy chỉ định kiểu đối số và kiểu giá trị trả về.

おわりに /
Lời kết

コメントや命名にここまでこだわって何になるんだ。と思うかもしれませんが、こうした工夫が仕様変更や追加開発に強い"保守性が高いサービス"を作り出します。 仕様変更や追加開発が行いやすいということは、我々自身が楽しんで開発を行うことにつながります。 特にこの記事で取り上げた内容は、今すぐにでも実践できる内容ばかりですので、サービスの発展のためにも、我々自身が楽しくコーディングをするためにも、ぜひ積極的に実践しましょう!!

Có lẽ bạn sẽ nghĩ việc quá để ý chi tiết về comment và naming thì sẽ được gì, nhưng việc đầu tư công phu như vậy sẽ tạo ra một "service có tính bảo trì cao" để dễ thay đổi specification và phát triển bổ sung. Khi dễ thực hiện thay đổi specification và phát triển bổ sung sẽ dẫn đến việc chúng ta thích thú thực hiện phát triển hơn. Đặc biệt là nội dung được đề cập trong bài viết này đều là nội dung có thể thực hành ngay lập tức, vì vậy chúng ta hãy tích cực thực hành để phát triển service và để chúng ta coding một cách thích thú !!

さて、次回は「ループとロジックの単純化」についてまとめます!!

Và sau đây, lần tiếp theo tôi sẽ tóm tắt về "Đơn giản hóa Loop and Logic" !!

ラクスのオフショア開発に関連する記事も、是非ご参考ください!
tech-blog.rakus.co.jp
career-recruit.rakus.co.jp


  • RAKUS Vietnam Co.,Ltd
    Rakus Việt Nam đang tích cực tuyển dụng kỹ sư (Java, PHP) và member QA. Bạn có muốn cùng tạo ra những sản phẩm SaaS với chất lượng như blog này không? Nếu bạn quan tâm, hãy ứng tuyển nhé.
    ラクベトナムでは、エンジニア(Java, PHP)やQAメンバの採用を積極的に行っています。 このブログのような品質を意識した自社SaaSプロダクトを一緒に作りませんか? ご興味ありましたら、是非応募をお願いします。 www.rakus.com.vn

  • エンジニア中途採用サイト
    ラクスでは、エンジニア・デザイナーの中途採用を積極的に行っております!
    ご興味ありましたら是非ご確認をお願いします。
    20210916153018
    https://career-recruit.rakus.co.jp/career_engineer/

  • カジュアル面談お申込みフォーム
    どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。
    以下フォームよりお申込みください。
    rakus.hubspotpagebuilder.com

  • イベント情報
    会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください!
    rakus.connpass.com

*1:原版の翻訳や要約ではありませんのでご注意ください。

Copyright © RAKUS Co., Ltd. All rights reserved.