2024.12.10
“放置系”なのにサイバー攻撃を監視・検知、「統合ログ管理ツール」とは 最先端のログ管理体制を実現する方法
リンクをコピー
記事をブックマーク
佐藤太一氏:みなさんこんばんは。「生産性の壁を突破しろ! コード自動生成」ということでお話しします。
まずは自己紹介から。電通国際情報サービス(ISID)の佐藤太一です。長いのでISIDの太一と呼んでください。私はふだん、GitHubやJiraといった、現代的な構成管理ツールの利用推進や、部門横断的な技術支援、会社の制度改善などを仕事にしています。
本題に入る前に、まずは軽く生産性の話をしておきましょう。物的生産性は計測しやすいので、よく生産性の議論をする上で利用されます。ソフトウェアの業界における生産量として計測しやすいのは、コードの行数です。各コードの1行あたりの価値が均質だとみなせるなら、非常に便利です。
しかし、実際にはコードの1行あたりの価値はまったく均質ではありません。コードの自動生成ツールを例にとって説明してみましょう。
今のプロジェクトでは、ほぼ私1人で書いた7,000行程度のツールから、現時点で18万行程度のコードを自動生成しています。このツールで、最終的には25万行以上のコードを自動生成する予定です。つまり、現時点でも25倍程度のレバレッジがあり、最終的には35倍以上のレバレッジを見込んでいるわけです。
単にコードの生産量だけを見るタイプの生産性については、ソースコードの自動生成技術があれば、その議論をほぼ無意味なものにできます。もし自動生成の対象になり得る領域をうまく見つけられるなら、桁違いの生産性を達成できるでしょう。
では、どんなものが自動生成の対象になるのでしょうか? それらには、いくつかの特徴があります。
まず、仕様の中に条件分岐が少なく、なんらかの表形式でデータを作りさえすればコードに落とし込めるもの。さらに、そこで使われるデータ構造やオブジェクトが、繰り返し同じ構造が現れるならよりよいでしょう。また、同じ処理構造が安定的に繰り返されるものは、自動生成しやすいです。
自動生成ツールを作ること自体も高度な生産活動ですし、直接的にアプリケーションを作るよりは難しいコードを書く必要があるので、少なくとも10倍程度のレバレッジが効く領域で自動生成したいですね。
とはいえ、採用しているプログラミング言語次第では、ある種のメタプログラミングを実施したり、ジェネリクスのような機能を使うことで、アプリケーションランタイムやコンパイラに自動生成を任せられることもあります。ファイルを出力するだけが、コードの自動生成ではありません。
本日の話題はGoにおける自動生成なので、込み入った言語機能は、現時点では実装されていません。ただし、ジェネリクスについては実装が進んでおり、その内容次第では、コードの自動生成で対象となる領域は狭くなるでしょう。
では、具体的にどんなものが自動生成の対象になるのでしょうか? ここでは説明しやすくするために、ドメインドリブンデザインの用語で説明します。
ValueObjectは、言語組み込みの型を使わずにドメイン特化の型を定義するために使うものです。私たちの実装では、メンバ変数は基本的に公開せず、Factory関数やEqualsメソッドを自動生成しています。
EntityはValueObjectとよく似ていますが、メンバ変数としてValueObjectが列挙されるところが違います。私たちの実装では、EntityにFactory関数は定義せず、構造体のメンバはすべて公開しています。
ここでいうRepositoryは、データベースアクセスするコードをカプセル化するためのものです。INSERTやPRIMARY KEYによるSELECT、DELETEはいつも同じコードになるので、自動生成するのが望ましいと考えています。
GORMのようなSQLを積極的に隠蔽するタイプのORM(Object-Relational Mapping)は、パフォーマンス障害の原因になりやすいので、私たちは利用しません。SQLはRDB(Relational Database)にアクセスするためのDSL(domain-specific language)として完成しているので、それを隠蔽したら問題は抽象化されないからです。
どんなものを自動生成の対象にするか、具体的にイメージしてもらえる状態になったところで、ここからは自動生成ツールをどのように設計するのかを説明していきます。
設計に先立って、自動生成ツールで利用する入力ファイルを紹介しましょう。(スライドを示して)今見せているのは、ドメイン用語辞書です。このファイルを使ってプロジェクト内で利用される用語を一元管理しています。
このファイルでは、アプリケーションコードにおける論理的な名称と実装型の名前、そして、内包する組み込み型の名前、データベースに永続化する際の型やバリデーションが1つのファイルで一覧できます。
今見せているのが、テーブル定義書です。これも、ごくごく単純な表になっています。少しこのフォーマットについて説明します。
論理名は、テーブル定義について議論する際に使う和名です。物理名は、DDL(Data Definition Language)を作成する際にカラム名として使います。そして、論理データ型に書かれた名前は、ドメイン用語辞書を参照しています。つまり、データベースの型定義はここにはありません。
複数のテーブルで論理的に同じ型だと見なせるカラムがあれば、それはすべて同じになることが保証できます。私たちが作るようなシステムでは、それほどカツカツに正規化してテーブル設計しないので、同じ論理データ型が複数のテーブルに表れることはよくあります。
(スライドを示して)ここまでで見せた2つのファイルから生成するコードの対応関係は、このようになっています。私たちがドメイン用語辞書から生成しているのは、ValueObjectです。
そして、ドメイン用語辞書を参照しながらテーブル定義から生成しているのが、RepositoryとEntity。また、それらのデータソースとなるテーブルのDDL、つまりCREATE TABLE文です。
本日は見せられませんが、私たちのプロジェクトでは、顧客の業務に強くひもづいていながら、ドメイン用語辞書を参照する設計ドキュメントはほかにもいくつかあり、それらからもコードの自動生成をしています。
入力ファイルを見せたので、ツールの設計について説明しましょう。まずコマンドです。今回作っているのは、Gitのようなサブコマンド方式のCUIアプリケーションで、1つのバイナリファイルからさまざまなファイルを出力できます。
コマンドはユーザー入力からモデルを構築する処理を呼び出し、得られた構造体をテンプレートに渡す役割を持ちます。コマンドを設計する際は、デフォルトの動作をDry runモードにします。Dry runモードとは、入力されたファイルを読み取ってモデルを構築するものの、テンプレートの呼び出しは行わないモードです。
例えば、オプションとして「--execute」を付けた時だけファイル出力を行うようにします。Dry runモードを付けておくと、CIサーバー上で設計ドキュメントをバリデーションできるようになったりします。標準出力や標準エラーを使ったログ出力のセットアップや、設定ファイルの読み込みもコマンドの役割です。
今回は、サブコマンド方式のCUIアプリケーションを難なく実装できるライブラリとしてCobraを採用しています。
モデルの実装で、普通の構造体に対して、しっかりと型の付いたメンバーを定義します。テンプレートで使うような型名や変数名を作るには、モデルにひもづく関数として定義すると便利です。
Excelから呼んだデータ構造をそのままテンプレートに渡すのではなく、いったんモデルに変換するのがコツです。これによって入力ファイルが持つデータ構造と、テンプレートを切り離せます。
例えば、セルの順序を入れ替えたくなったり、途中で新しい項目を足したくなることはいくらでもあります。最初に作った入力フォーマットが完璧だということはありません。こういうものを何度も作っている私でもそうです。
モデルを作り込む理由としてもう1つ伝えておきたいのは、「モデルのバリデーションはしっかりと作り込みましょう」ということです。
例えば、入力必須項目のチェックやテーブル定義におけるカラム名の重複、ドメイン用語辞書に登録されていない用語の利用などは、バリデーションで検知します。Excelファイルを読み込むためのライブラリとしては、Excelizeを利用しています。
テンプレートは、モデルを受け取ってファイルを出力する部分です。テンプレートの実装方式にはさまざまなものがありますが、今回は内部DSL方式のライブラリであるJenniferを採用しました。
内部DSL方式では、ソースコードの自動生成をやりやすいかたちで再定義したプログラミング言語の構文を使います。
DSL型のAPIでは、コードを書いてコンパイルが通った時点で、生成されるコードのコンパイルが通ることがある程度保証されています。つまり、ある程度の大きなコードを一気に生成しても、生成物の状態が予測可能なのです。
(次回に続く)
関連タグ:
2024.12.10
メールのラリー回数でわかる「評価されない人」の特徴 職場での評価を下げる行動5選
2024.12.09
10点満点中7点の部下に言うべきこと 部下を育成できない上司の特徴トップ5
2024.12.09
国内の有名ホテルでは、マグロ丼がなんと1杯「24,000円」 「良いものをより安く」を追いすぎた日本にとって値上げが重要な理由
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
2024.12.10
職場であえて「不機嫌」を出したほうがいいタイプ NOと言えない人のための人間関係をラクにするヒント
2024.12.12
会議で発言しやすくなる「心理的安全性」を高めるには ファシリテーションがうまい人の3つの条件
2024.12.06
嫌いな相手の行動が気になって仕方ない… 臨床心理士が教える、人間関係のストレスを軽くする知恵
PR | 2024.11.26
なぜ電話営業はなくならない?その要因は「属人化」 通話内容をデータ化するZoomのクラウドサービス活用術
2024.12.11
大企業への転職前に感じた、「なんか違うかも」の違和感の正体 「親が喜ぶ」「モテそう」ではない、自分の判断基準を持つカギ
PR | 2024.11.22
「闇雲なAI導入」から脱却せよ Zoom・パーソル・THE GUILD幹部が語る、従業員と顧客体験を高めるAI戦略の要諦