株式会社ユーザベースの技術チームブログです。最近リリースされたプロダクションコードにようやくGo言語が採用されました。今回はGo言語でオブジェクト指向プログラミングで型表現についてのテクニックや考え方の基礎を紹介します。型を定義するオブジェクト指向プログラミングの基本として「型」で表現を体現します。structはGoの値であり型です。例題:エンジニアだけが所属できる、SPEEDAプロダクトというユニットに、tkitsunaiという名前のエンジニアが所属している。デザイナーだけが所属できる、SPEEDAデザインというユニットに、hiranotomokiという名前のデザイナーが所属している。例題を悪い例として実装します。})利用する実装コードは以下です。}型で厳格さを作り、その型を洗練させる上の構造体定義はプリミティブな型で表現されています。例題に対して型でほとんど表現できておらず悪い例といえます。ユニットが変数名だけで表現されており、デザインユニットにエンジニアが入ってしまう可能性があるtkitsunaiがそもそも人ではない可能性があるtkitsunaiかhiranotomokiという文字だけでは、エンジニアかデザイナーか判断できないetc...プリミティブ型を多用することによって起きる問題を、型の厳格さを加えることで排除します。プリミティブ型をなくすGo言語には型宣言によって、基本型もしくは定義された構造体を別名で再定義することが可能です。})利用する実装コードは以下です。}少しだけ良くなりました。この改良でProductUnitに人以外が混在することはなくなりました。人の名前とユニットの名前が混在することもなくなりました。Unitの特性を型で表現する例題を見直すと、プロダクトユニットにはそれぞれ特性があります。プロダクトユニットならばエンジニア、デザインユニットならばデザイナーである必要があります。現在のままでは、tkitsunaiという人がデザインチームに入れられるかもしれません(それはそれで楽しそうですが)。これも型で制限していきます。})利用する実装コードは以下です。}この改良によって、各ユニットで所属できる型が制限されたので、Engineerであるtkitsunaiはデザインユニットに入ることはできなくなりました(残念)。型に厳格さを求める完全コンストラクタを活用する現時点では、PersonNameやUnitNameにはどのような名前も許されていますが、オブジェクト生成時にルールを適用させることで、型を利用する場合にエラーとできるようにします。いわゆる完全コンストラクタを目指します。Go言語にはコンストラクタはありませんが、慣習としてPrefixにStruct名にNewをつけた関数を用意し、structとerrorを返すようにします。ユニット名が必要ですエラーを握りつぶされてしまったら元も子もないですが、これでUnitNameのルールを生成時に確認でき、空文字なユニット名は作ることはできなくなりました。このように、UnitNameを持つProductUnitおよびDesignUnitは、UnitNameの完全コンストラクタを通じて、型とそのルールが表現されていきます。ファーストクラスコレクションと型定義によってメンバーに対する操作を制限するProductUnitのフィールドであるMembersは[]Engineer型で表現されています。この状態では、ProductUnitがこのコレクションを直接操作しなければならず、コレクションを壊しかねません。型を抜き出して、ファーストクラスコレクションとしてstructを再定義し、操作を制限させることでコレクションの壊れにくさを作ります。増やす操作しかできない}上記の実装によって、増やすメソッドは存在するが、減らすメソッドを定義しないことで、コレクションに対する操作を制限できました。[]Engineerとしても良いかもしれません。列挙型で表現力を高めるプログラム言語を持ったエンジニアを定義するような値とそれを持った型を作るならば、型表現とコレクションを応用して表現力を高めることができそうです。}}これもただの列挙型ではなく、型に別名をつけることで厳格化させます。構造体埋め込みで表現をする構造体埋め込みを利用して型定義に幅を持たせます。}}利用する実装コードは以下です。tkitsunai.Greet()}GoEngineer型のフィールドperson型定義によって型の恩恵を受けられます。同時にperson型はパッケージ外に公開していないため、完全コンストラクタを経由してGoEngineer型を利用すれば、personの詳細実装が外に漏れずに済みます。構造体の埋め込みは普段活用していませんが、型をまとめるためだけでなく、制限範囲を限定することもできるため、応用がしやすいと思います。まとめ今回はGo言語における型表現について、ほんの一部だけ紹介しました。プリミティブな型を作らない最初から汎用的な型を作らない完全コンストラクタで型が示す表現力を高めるファーストクラスコレクションで操作を制限する列挙であるiotaも別名で型定義して利用する構造体埋め込みを上手く利用する関連しているオブジェクト指向エクササイズも面白いので、気になる方はぜひ調べてみてください。型を定義するという行為は、ルールや制限を明確かつ厳格化することであり、表現力を豊かにする行為そのものです。オブジェクトには何かしらのルールが存在し、型そのものや、型自体で知識やルールを表現/体現する効果があります。最近はドメイン駆動設計が随分と盛り上がりを見せており、ドメインレイヤの実装では、ドメインを型と型のメソッドで知識を表現/体現します。オブジェクト指向プログラミングです。型の恩恵を受けられるチャンスを増やしていきましょう。最後に、この言葉をおくります。宛にリプライをしてみてください。型が大好きな方もこれから取り組みたい方も、様々な強みを持った弊チームで働きませんか?応募はこちらから。単一責任のクラスを設計する」をハン...今日は。開発している濱口です。多国通貨」をハンズオンしたら快適で楽しかった今日は。SPEEDAの開発をやっている濱口です。SPEEDA開発チー...2019-09-17Rustで非同期リクエストでハマったことこんにちは!SPEEDAプロダクト開発チームの成です。Kubernetesのネットワーク...こんにちは。SPEEDA開発チームの鈴木です。Wicketのイベントシステム徹底活用(実用サンプルもあるよ)SPEEDAの開発してます矢野です。社外から参画してます。»プロフィール『経済情報で、世界を変える』をミッションに、企業・業界情報プラットフォーム「SPEEDA」やソーシャル経済ニュース「NewsPicks」、ABMを強力にサポートする「FORCAS」、スタートアップの情報収集を圧倒的効率化「entrepedia」などを提供する株式会社ユーザベースの技術チームブログです。多国通貨」をハンズオンしたら快適で楽しかったGo言語でオブジェクト指向プログラミングの基本(型編)月別アーカイブ検索@Uzabase_Techさんのツイートスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。