システムの透明性
システム監視について整理しておきたいなぁと思い、Release It!という本があったので、週末読んだ内容をメモしておきます。 監視は第17章の「透明性」に書かれているものです。 要約なので、ほとんどは書中からの引用です。
続きを読むUseCaseの再利用性
Clean ArchitectureにはUseCase層が定義されていますが、このUseCaseが一体どういうものなのか度々わからなくなるので、自分の考えをまとめてみるエントリです。
Clean Architectureについてはこちら
日本語訳:クリーンアーキテクチャ(The Clean Architecture翻訳)
以降、概念を”ユースケース”、実装されるモノを”UseCase”と表記することにします。 (同じっちゃ同じなんですが、指してるものがところどころ変わるので表記分けをしています。) また、Webアプリケーションを想定しています。
ユースケースとは何なのか
続きを読むドメインイベントを設計する
第3回Reactive System Meetup in 西新宿のLTで発表をしてきました。
reactive-shinjuku.connpass.com
LTという都合上、含めたかったけれど泣く泣く削ったボツネタも併せて補足するエントリです。 (例によって長いです。)
続きを読むマイクロサービスとDDDをGo言語とScala+Akkaで比較したらEventSourcingの話にもなって面白かったまとめ
JSでもオブジェクト指向ライクに書きたくなるので覚書
JSでオブジェクト指向ライクに書こうと思ったときにES6もBabelも使えない環境向けの覚書です。
ここではクラスのようにデータと振る舞いをまとめられる程度のところを到達点としています。(オブジェクト指向とは云々などは本旨から外れるので"ライク"という表現に留めておきます。)
参考書籍は「オブジェクト指向JavaScriptの原則」です。この本はC#やJavaなどの経験はあってJavaScriptへの取っ掛かりが欲しい人にオススメです。
なお、私はJavaScriptに関しては初心者同然です...
TypeScriptとかおいしそうですね...
基本のカタ
function Foo(name) { // コンストラクタ this.name = name; // データ定義(Public) } Foo.prototype = { constructor: Foo, bar: function() { // メソッド定義 console.log('foo.bar'); }, toString: function () { // オーバーライド console.log(this.name); } };
まず、 function Foo
のようにコンストラクタを定義します。
先頭1文字が大文字だとコンストラクタであることが期待されるようです。このとき、 var foo = new Foo('foo');
のようにnewを使ってオブジェクトを生成することができます。
このコンストラクタの中に this.name = ...
のようにPublicなデータを定義することができます。
メソッドもここに定義することができますが、そうすると全てのインスタンスで関数オブジェクト(?)を持つことになり非効率です。
そこで、 Foo.prototype
に対してメソッド(関数オブジェクト)の集まりを設定することで、同じ振る舞いを持ったオブジェクトを生成できるようにします。
JavaScriptでは、すべての関数はオブジェクトなので、どこかでprototypeに対してメソッドを追加したり、変更したりできてしまいます。
オーバーライドについても、同名であるだけで上書きがされます。
この辺りはプロトタイプチェーンであることの特性なので、気をつけて運用しましょう。
constructor: Foo
のようにわざわざコンストラクタはこれだと明示していますが、これを行わない場合constructorがObjectになってしまいます。
これはprototypeに対して {...}
の形で丸ごと設定しているため、本来のconstructorが失われてしまうことが原因です。
Foo.prototype.bar = function(){...}
のように一つ一つ設定するか、constructorを忘れずに明示するようにする必要があります。
その他、書籍では Object.defineProperty
を使った方法や即時関数のなかでオブジェクトを生成する方法なども紹介されていますが、ここでは割愛します。
プライベートメンバ
プライベートな変数を持ちたいような場合、上記のコンストラクタパターンでは、以下の様な方法で定義することができます。
function Person() { var age = 25; this.getAge = function() { return age; }; this.growOlder = function() { age++; }; }
ただし、この方法では、そのプライベートメンバへ参照するために内部にメソッドなどを定義する必要があり、前述のようにprototypeではなくインスタンスに配置されるため非効率ではあります。 しかし、プライベートなメンバを定義するには、今のところこの方法しか無いようです。 (全てのインスタンスで共有されても良い場合は、即時関数のなかでprototypeにメソッドを定義するなどすることは可能。)
継承
オブジェクト継承という方法もありますが、ここではコンストラクタ継承を取り上げたいと思います。 コンストラクタ継承では、継承元のprototypeとObject.createを使ってプロトタイプチェーンのつながりを実現します。
function Rectangle(length, width) { this.length = length; this.width = width; } Rectangle.prototype.getArea = function() { return this.length * this.width; }; function Square(size) { this.length = size; this.width = size; } Square.prototype = Object.create(Rectangle.prototype, { constructor: { configurable: true, enumerable: true, value: Square, writable: true } });
mixin
書籍では継承の方法から派生してmixinに言及されています。 mixinは強力ではありますが、そこに継承のように参照関係がつくられないため、比較的規模の小さい機能での使用に適していると書籍では述べられています。 多くの機能を追加したい場合や、機能の提供源を把握しておきたい場合は継承を使うことが推奨されるようです。
function mixin(receiver, supplier) { if (Object.getOwnPropertyDescriptor) { // ES5以降 Object.keys(supplier).forEach(function (property) { var descriptor = Object.getOwnPropertyDescriptor(supplier, property); Object.defineProperty(receiver, property, descriptor); }); } else { for (var property in supplier) { if (supplier.hasOwnProperty(property)) { receiver[property] = supplier[property]; } } } return receiver; }
これは以下のように使うことができます。
function Foo() { // ... } function Bar() { // ... } // プロトタイプへのmixin mixin(Foo.prototype, Bar.prototype); // インスタンスへのmixin var foo = new Foo(); mixin(foo, Bar.prototype);
終わりに
コンパイル、静的型付けチェックが欲しいですね。
せめてJSDocを書きましょう。IDEなどを使っていればコード補完も享受できるようになります。
参考
DDD座談会に際して素振りをしていた
DDD座談会のパネラーとして登壇させていただきました。
素振り
予め参加者の方々からいただいた質問(テーマ)に対して、予行練習というか、ちょっと自分の考えを先にまとめていたのですが、予想通りテーマひとつひとつが盛り上がったので全部を話しきることができませんでした。 折角なのでここに公開しておきます。 ところどころ、座談会終わっての後書きも追記しています。
なお、あくまで私見ということでよろしくお願いします。座談会のまとめ記事というわけではありませんので、悪しからず。
各人のコンテキストで、こんな解釈あるよ等あると思いますので、Twitterでもコメントでもフィードバックいただければ幸いです。
続きを読む