自前でクライアントサイドMVCのModelとView用ライブラリ作った
自前でクライアントサイドMVCのModelとView用ライブラリ作った。
コンセプトは、以下のような見慣れたクラス定義の書き方を崩さずかけるようにすること。
/** * サンプルクラス */ var SampleClass = function () { // 何か処理 }; /** * サンプルメソッド */ SampleClass.prototype.sampleMethod = function () { console.log('sampleMethod'); };
今回作ったBellTreeMVを使用する場合、例えばModelを定義する場合以下のように書く。
/** * サンプルModel */ var SampleModel = function () { BellTreeMV.Model.call(this); }; BellTreeMV.inheritPrototype(SampleModel.prototype, BellTreeMV.Model.prototype); SampleModel.prototype.sampleMethod = function () { console.log('sampleMethod'); };
必須なのは
BellTreeMV.Model.call(this);
と
BellTreeMV.inheritPrototype(SampleModel.prototype, BellTreeMV.Model.prototype);
の行のみ。 あとは昔からある見慣れたコンストラクタ関数の定義と、prototypeにメソッドを定義しているだけ。
まだまだライブラリと呼ぶにはあまりに拙く機能もすくないけど、わりと自己満足はできてるし、オブザーバパターンの良い勉強になった。
React + browserify 用 gulpfile メモ
React で browserify を使用する場合用のgulpfileを作ったのでメモ。 99%自分のメモ用。
uglify がファイルを縮小させるやつ。 plumber がビルドで失敗しても、ファイル変更の監視をやめないようにするやつ。 reactify がJSXをJavaScriptに変換するやつ。
var gulp = require('gulp'); var uglify = require('gulp-uglify'); var plumber = require('gulp-plumber'); var browserify = require('browserify'); var source = require("vinyl-source-stream"); var reactify = require('reactify'); var buffer = require('vinyl-buffer'); gulp.task('dist', function(){ var bundler = browserify('./script/src/main.jsx', { debug: true }); return bundler .transform(reactify) .bundle() .pipe(plumber()) .pipe(source('build.js')) .pipe(buffer()) .pipe(uglify()) .pipe(gulp.dest('./script/dist/')); }); gulp.task('watch', function() { gulp.watch('./script/src/*.js', ['dist']); gulp.watch('./script/src/*.jsx', ['dist']); gulp.watch('./script/src/**/*.js', ['dist']); gulp.watch('./script/src/**/*.jsx', ['dist']); }); gulp.task('default', ['dist', 'watch']);
Effective Java の BuilderパターンをJavaScriptで書いてみた
Javaの参考書のなかでよくおすすめと言われている Effective Java で紹介されている Builder パターンを、JavaScript で書いてみた。
Effective Java ってなんやそれ、っていう方はこちら。
Amazon.co.jp: EFFECTIVE JAVA 第2版 (The Java Series): Joshua Bloch, 柴田 芳樹: 本
普通に Java で書かれたコードについてはこちら。Effective Java で紹介されているBuilderパターン意外も紹介されています。とてもわかりやすかったです。
Javaで書くBuilderパターンのパターン - Qiita
Builder パターンを使用しない場合
ここでは、以下のユーザ情報を登録できるシステムを想定して、ユーザ情報を保持するオブジェクトの生成を例にみていく。 * 名前(必須項目) * 年齢 * 郵便番号 * 住所 * 血液型 * 星座 * 好きな食べ物
以下 Builder パターンを使用しない場合のコード。 引数ですべての属性を指定している。
/** * ユーザクラス * @param {String} name * @param {Number} age * @param {String} postalCode * @param {String} address * @param {String} phoneNumber * @param {String} boodType * @param {String} constellation * @param {String} favoriteDish */ var User = function (name, age, postalCode, address, phoneNumber, boodType, constellation, favoriteDish) { 'use strict'; if (!name) { throw new Error('必須項目[名前]が未設定です。'); } this.name = name; this.age = age; this.postalCode = postalCode this.address = address; this.phoneNumber = phoneNumber; this.bloodType = boodType; this.constellation = constellation; this.favoriteDish = favoriteDish; }; User.prototype.toString = function () { 'use strict'; var string = (' 名前: ' + this.name + ' 年齢: ' + this.age + ' 郵便番号: ' + this.postalCode + ' 住所: ' + this.address + ' 電話番号: ' + this.phoneNumber + ' 血液型: ' + this.bloodType + ' 星座: ' + this.constellation + ' 好きな食べ物: ' + this.favoriteDish) ; return string; }; // 新規のユーザを作成 var user = new User('数多の世界を救済した勇者 ああああ', 60, 'XXX-XXXXX', '勇者の城(旧魔王の城)', 'XXX-XXXX-XXXXX', 'AB', '乙女座', '牛ヒレ肉とフォアグラのロッシーニ');
このコードの悪いところ (1つめ)
オブジェクトを生成するタイミングで、引数の順番を間違いやすい。 第二引数くらいまでは、まぁ間違わないでしょう。 ただ、第7引数、第8引数にあたりになると、どっちに「星座」で、どっちに「好きな食べ物」設定するんだ?ってなる。
// 新規のユーザを作成 var user = new User('数多の世界を救済した勇者 ああああ', 60, 'XXX-XXXXX', '勇者の城(旧魔王の城)', 'XXX-XXXX-XXXXX', 'AB', '乙女座', '牛ヒレ肉とフォアグラのロッシーニ'); // ↑ こんなに順番覚えていられない。やってられっかばーか ってなる。
このコードの悪いところ (2つめ)
「名前」と「好きな食べ物」だけ設定したい場合も第2引数〜第7引数を指定しなければならない。 コードにすると以下のようになる。
// 新規のユーザを作成 var user = new User('数多の世界を救済した勇者 ああああ', undefined, undefined, undefined, undefined, undefined, undefined, '牛ヒレ肉とフォアグラのロッシーニ'); // こんなの絶対おかしいよ
Builder パターンを使用した例
Builder パターンを使用して、以下のようにコードを改修した。
/** * ユーザクラス * @param {Builder} builder */ var User = function (builder) { 'use strict'; this.name = builder.name; this.age = builder.age; this.postalCode = builder.postalCode; this.address = builder.address; this.phoneNumber = builder.phoneNumber; this.bloodType = builder.bloodType; this.constellation = builder.constellation; this.favoriteDish = builder.favoriteDish; }; User.prototype.toString = function () { 'use strict'; var string = (' 名前: ' + this.name + ' 年齢: ' + this.age + ' 郵便番号: ' + this.postalCode + ' 住所: ' + this.address + ' 電話番号: ' + this.phoneNumber + ' 血液型: ' + this.bloodType + ' 星座: ' + this.constellation + ' 好きな食べ物: ' + this.favoriteDish) ; return string; }; /** * ユーザインスタンスを生成するためのビルダークラス */ User.Builder = function () {}; /** * 名前を設定します。 * @param {String} name * @returns {Builder} */ User.Builder.prototype.name = function (name) { 'use strict'; this.name = name; return this; }; /** * 年齢を設定します。 * @param {Number} age * @returns {Builder} */ User.Builder.prototype.age = function (age) { 'use strict'; this.age = age; return this; }; /** * 郵便番号を設定します。 * @param {String} postalCode * @returns {Builder} */ User.Builder.prototype.postalCode = function (postalCode) { 'use strict'; this.postalCode = postalCode; return this; }; /** * 電話番号を設定します。 * @param {String} phoneNumber * @returns {Builder} */ User.Builder.prototype.phoneNumber = function (phoneNumber) { 'use strict'; this.phoneNumber = phoneNumber; return this; }; /** * 住所を設定します。 * @param {String} phoneNumber * @returns {Builder} */ User.Builder.prototype.address = function (address) { 'use strict'; this.address = address; return this; }; /** * 血液型を設定します。 * @param {String} bloodType * @returns {Builder} */ User.Builder.prototype.bloodType = function (bloodType) { 'use strict'; this.bloodType = bloodType; return this; }; /** * 星座を設定します。 * @param {String} constellation * @returns {Builder} */ User.Builder.prototype.constellation = function (constellation) { 'use strict'; this.constellation = constellation; return this; }; /** * 好きな食べ物を設定します。 * @param {String} favoriteDish * @returns {Builder} */ User.Builder.prototype.favoriteDish = function (favoriteDish) { 'use strict'; this.favoriteDish = favoriteDish; return this; }; /** * ユーザインスタンスを生成して返します。 * @throws {Error} * @returns {User} */ User.Builder.prototype.build = function () { 'use strict'; if (!this.name) { throw new Error('必須項目[名前]が未設定です。'); } return new User(this); }; var userBuilder = new User.Builder(); var user; userBuilder .name('数多の世界を救済した勇者 ああああ') .age(60) .address('勇者の城(旧魔王の城)') .phoneNumber('XXX-XXXX-XXXXX') .postalCode('XXX-XXXXX') .favoriteDish('牛ヒレ肉とフォアグラのロッシーニ') .constellation('乙女座') .bloodType('AB') ; user = userBuilder.build();
ポイント
setter的なメソッド ↓ で builder 自身を返しているところ。
/** * 好きな食べ物を設定します。 * @param {String} favoriteDish * @returns {Builder} */ User.Builder.prototype.favoriteDish = function (favoriteDish) { 'use strict'; this.favoriteDish = favoriteDish; return this; };
これにより、jQuery のメソッドチェーンとか、Java の StringBuilder の append("~").append("~~~~~").append("") みたいに書けるようになる。イケメン。
改修前のコードの問題が解決されているか
改修前のコードの以下の問題が解決できているかみてみる。
- 引数の順番を覚えておかないといけない
- 設定不要なパラメータも指定しなければいけない
var userBuilder = new User.Builder(); var user; // 各属性を設定する場合、その属性に設定するためのメソッドを呼べばよいため、 // 順番をきにする必要はなくなっている。 // また、設定したくない属性がある場合、 // その属性を設定するためのメソッドを呼ばなければよいため2つ目の問題も解決されている。 userBuilder .name('数多の世界を救済した勇者 ああああ') .age(60) .address('勇者の城(旧魔王の城)') .phoneNumber('XXX-XXXX-XXXXX') .postalCode('XXX-XXXXX') .favoriteDish('牛ヒレ肉とフォアグラのロッシーニ') .constellation('乙女座') .bloodType('AB') ; user = userBuilder.build();
結論
やっぱりBuilderパターンってすげーや。
HTML5プロフェッショナル認定試験レベル2受験の際に俺が参考にした本と感想とか
今回は半年くらい前に受験した HTML5 プロフェッショナル認定試験 Level2 について。
レベル1については前回の記事で書いているので、そっちで。
結果
1発合格でした。が、正答率は、たしか 75% くらいで、わりとギリギリ合格だったはず。 時間的には余裕をもって見直す時間もあったと思う。
試験内容
「HTML5プロフェッショナル」とか言ってるけど、レベル2の試験問題は、ほぼほぼ JavaScript です。 HTML5で追加されたAPIの使用方法の問題が大半で、レベル1の問題のような、HTMLタグの書き方とか順番とかの問題はほとんど出題されないです。 詳しくは、公式の出題範囲を。
受験対策として使用した参考書
まずメインで使用した参考書 レベル1では紙の書籍を購入したが、レベル2ではkindle版を使用。 amazon の評価は低いけど、自分はこの本をメインで使用して合格しました。 この本の最後にある模擬試験を中心に勉強した。
もう一冊、こちらは紙の書籍を購入。 ただし、内容的には上の本の方が詳しく書かれている気がする。 amazon のレビューにもある通り、かなーり簡単に、さらっとJavaScriptを解説しています。 こちらは各章ごとに演習問題がついている。が、解説もあっさり気味。
参考にしたWebサイト
レベル1の時と同様、公式サイトにも例題があります。 この例題も2、3回繰り返し解きました。 これから受験する人は、この問題も絶対やっておくべき。
あとは、出題範囲に含まれる SVG 関連で、以下のサイトの SVG についてのページも参考になった。あとイラストが可愛い。 (左側メニューの 「SVG(Scalable Vector Graphics)」→「SVGってなあに?」)
感想とか
自分は元々 JavaScript が好きな人間なので、勉強していて楽しかったです。 ぶっちゃけ、Geolocation API とか試験対策の勉強しなければ、ずっと知らないままだったし。
あと、結構ちゃんとJavaScriptの言語仕様とかも出題範囲に含まれていて、
// 以下の処理でそれぞれ何が出力されるか答えろ console.log( false == 0 ); console.log( false === 0 );
みたいな問題も出題されるので、(ちなみに上は true が出力されて、下は false が出力される。)細かいところをおろそかにしていると、わりとしねるなーって思いました。
まぁ、なんか Web の技術が好きで、なんか資格とりたいなーって人には向いてる資格なのかなーって思いました。少なくとも俺は勉強になりました。まる。
HTML5プロフェッショナル認定試験レベル1受験の際に俺が参考にした本と感想とか
jBellTree鈴木です。
今回は1年くらい前に受験した HTML5 プロフェッショナル認定試験 Level1 について。 Level2 も取得済だけど、まずは Level1 の受験のレポートから。
結果
1発合格でした。 正答率は、たしか 80% くらいだったと思います。
時間的には1回全て時終わるのには十分な時間だったと思いますが、 全問見直す時間は無かったように思います。
問題の内容
参考書を隅から隅まで頭にたたきこんでおけば解けるような問題でした。 ただし、1問だけ記述の問題があったように思います。 どんな問題だったかは、すんませんわすれました。
あと、こんなん知らんわ!っていう問題で、
「iPhone で 以下のタグを表示したときの見た目を選べ」
みたいな問題が出たのを覚えています。
使用した参考書
そもそも俺が受験した時は、公認の参考書がコレしかなかった。 kindle 版も出ているが、当時の俺は 「電子書籍なんかで勉強しても頭に入らねーよwww」 と思っていたので、紙の書籍を買いました。 Kindle版のリンクも一応貼っておきます。
内容としては、amazon のレビューにある通り、とにかく試験範囲を網羅することを目的としている感じです。 たしか本の最後の方に模擬試験1回分が収録されていました。
amazon のレビューでは評価がそれほど高くないようだけれど、自分はこの本のおかげで合格できたし、この本がなければ合格できなかったと思います。
参考にしたWebサイト
泣く子もだまる公式サイトで、例題を用意してくれています。 自分は上記の参考書の問題と、以下の公式の例題を各3回くらい解き直してから受験しました。
あとたしか、参考書で分からなかったタグがあった時、↓のサイトも参考にしたように思います。
感想とか
ひたすら暗記するのが大変だったのを覚えています。 ただし、 HTML5 で削除された要素 HTML5 で意味が変わった要素 HTML5 で追加された要素 CSS3 で使えるようになった機能 などなど、体系的にまとめられているので、 いままで、HTMLなんて適当にかけばいいんでしょ? みたいに思っている人は、目から鱗な内容だと思います。
あとこの記事が、これから HTML5 プロフェッショナル認定試験 Level1 を受験する人の参考になれば幸いです。
Selector API の使い方
Selector API の使い方をメモっとく
Selector API は CSS のセレクタ( #ok_button とか .button_area )を使用して、HTMLの要素を取得できるAPI。 以下のメソッドがある。
・document.querySelector
例
document.querySelector('.test'); // class属性に test が指定されている要素のうち最初の要素を指定する
・document.querySelectorAll
例
document.querySelectorAll('.test'); // class属性に test が指定されている要素すべてを配列で返す
今までは document.getElementById() とか document.getElementsByClassName() とか をセレクタ別で使い分けていて、それが嫌な場合は大抵jQueryを使っていたけど、 jQueryを使うまでもなく、でもいちいちメソッド使い分けるのめんどーだなーって時使えるかもしれない。 あと、CSSに慣れているデザイナと相性いいかもしれない。
実際のソースコードものせとく
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>Query Selector テスト</title> </head> <body> <p> <button id="button1">querySlectorメソッド使用ボタン</button> <button id="button2">querySlectorAllメソッド使用ボタン</button> </p> <ul> <li class="test_class">変更前</li> <li class="test_class">変更前</li> <li class="test_class">変更前</li> <li class="test_class">変更前</li> <li class="test_class">変更前</li> </ul> </body> <script> // querySelector() メソッドを使用してイベントリスナを設定 document.querySelector('#button1').addEventListener('click', function () { // querySelectorはセレクタで取得できる要素のなかで最初の要素を返す document.querySelector('.test_class').innerHTML = '変更された'; }, false); // querySelector() メソッドを使用してイベントリスナを設定 document.querySelector('#button2').addEventListener('click', function () { var nodeList , i ; // querySelectorAll() は querySelector()と異なり、セレクタで取得できる要素すべてを配列で返す nodeList = document.querySelectorAll('.test_class'); for (i = 0; i < nodeList.length; i++) { nodeList[i].innerHTML = '変更された'; }; }, false); </script> </html>
Oracle SQL Developer のフォント/背景色を変更する方法
Oracle SQL Developer をインストールするたびに、
「フォント変えたいなー、背景色変えたいなー」
「あれ?どこから変更するんだ?」
ってなっていたので、変更手順をメモっとく。 画面はMac版だけど、Windows版でも似たような手順で出来るはず。
1.設定画面までの行き方
「Oracle SQL Developer」 → 「Preferences」
2.背景色の変え方
2-1. 背景色だけの変え方
プリファレンス画面の左側メニュー → 「コードエディタ」 → 「PL/SQL構文の色指定」 → 「背景」
変更をしたらプリファレンス画面右下の 「OK」ボタンを押す。
2-2. テーマ毎いっきに変える方法
今回記事を書きながら初めてこんな機能あるのを知った。 SQL Developer なかなかやるじゃねーか。
以下の手順でエディタ部分のテーマを変えられる。SQL Developer ではスキームって言うらしい。
プリファレンス画面の左側メニュー → 「コードエディタ」 → 「PL/SQL構文の色指定」 → 「スキーム」
変更をしたらプリファレンス画面右下の 「OK」ボタンを押す。
3. フォントの変え方
フォントの変更も、背景色の変更と同様にプリファレンス画面から行える。
手順は以下のとおり。
プリファレンス画面の左側メニュー → 「コードエディタ」 → 「フォント」 → 「フォント名」
変更をしたらプリファレンス画面右下の 「OK」ボタンを押す。
おわりに
まぁ、どんなに開発環境の見た目を美しても、既存のスパゲッティコードが変わるわけではないんだけどね…