27 Nov 2014, 13:58

お手軽お気楽コードレビューシステム! codebrag に驚いた

はじめに

Subversion をつかっていて, ソースコードレビューでコードにコメントを書きたいと思った.

なにか, お手軽にためせるツールはないか探して見たところ, Codebrag というものを見つけたので試す.

Codebrag とは

オープンソースのコードレビューツール.

サーバにインストールして, Web 画面からコードレビューができる.

Git と Subversion に対応しているようだ. Subversion は, git-svn をつかって使えるようにしているようだ.

インストール

インストール手順は以下にある.

以下から, ダウンロード. ダウンロードでメールアドレスを入れないといけないのがちょっといやだ.

もしかしたら, wget でとれるかも..未検証.

wget http://codebrag.com/latest/codebrag.zip
unzip codebrag.zip

設定

リポジトリクローン

まずは, ダウンロードした zip を解凍.その後, repos ディレクトリに移動.

repos ディレクトリにリポジトリを clone する.

  • Git: git clone
  • Subversion: git svn clone
cd codebrag-2.3/repos
git clone git@github.com:tsu-nera/tdd_by_example.git

設定ファイル編集

codebrag.conf を編集する. リポジトリ認証のための設定を記述.

repository {
    username = "hogehoge"
    password = "password"
}

サンプルの.conf

起動

以下で起動.

./codebrag.sh start         # Unix/OS X
codebrag.bat                # Windows

URL にアクセス. Default は http://localhost:8080

しばらく時間がかかるからコーヒーでも飲んでなさいというメッセージのあ とに, ログイン画面が出てくる.

画面リフレッシュ後, ログイン. UI はかなりオシャレ!!

コードに対して, コメントやイイネ! をすることができる! すごい!

感想

正直, こんなに簡単に導入できて, おしゃれなツールだったので驚いている.

昔, ReviewBoard をインストールしようとしたが, ものすごく苦労した.

これは, インストールがとても簡単なところが気に入った.

gitbucket という,github を模倣して 簡単に github サーバをローカルに立てるツールがあるが, それと同じくらいに簡単. ライバルくらい, 簡単.

仕事で使いたいな・・・使わせてくれるかな・・・

下っ端で権力がないので無理かな…へぇ.

Bookmarks

26 Nov 2014, 16:12

Java の無名クラスにパラメータを渡す方法のメモ

はじめに

Java で, オブジェクト自体にタイムアウト機能を持たせることを考えた. (普通ならば, 外部のオブジェクトが監視するのかな??)

コード

<div class="outline-text-3" id="text-unnumbered-2">
  <p>
    こんなコードを書いた. タイムアウトになったら, 自分自身を Set から削除する.
  </p>

  <p>
    [sourcecode language=&#8221;java&#8221; title=&#8221;&#8221; ]<br /> import java.util.HashSet;<br /> import java.util.Set;<br /> import java.util.Collections;
  </p>

  <p>
    public class TimeoutObjectSample {<br /> public static void main (String[] args) {<br /> new B ();<br /> }<br /> }
  </p>

  <p>
    class B {<br /> Set<A> set;</p> 

    <p>
      public B () {<br /> set = Collections.synchronizedSet ( new HashSet<A>() );<br /> A a = new A (this);</p> 

      <p>
        set.add (a);<br /> System.out.println (&#8220;size is &#8221; + set.size ());<br /> a.start ();<br /> }
      </p>

      <p>
        public synchronized Set<A> getSet () {<br /> return set;<br /> }</p> 

        <p>
          }
        </p>

        <p>
          class A {<br /> B parent;
        </p>

        <p>
          public A (B parent) {<br /> this.parent = parent;<br /> }
        </p>

        <p>
          void start () {<br /> System.out.println (&#8220;start&#8221;);
        </p>

        <p>
          new Thread (new Runnable () {
        </p>

        <p>
          public void run () {<br /> try{<br /> Thread.sleep (1000);<br /> } catch (InterruptedException e){<br /> } finally {<br /> Set<A> set = parent.getSet ();<br /> System.out.println (&#8220;I will die&#8221;);<br /> set.remove (this);<br /> System.out.println (&#8220;size is &#8221; + set.size ());<br /> }<br /> }<br /> }).start ();<br /> }<br /> }<br /> [/sourcecode]</p> 

          <p>
            しかし, これがうまく動かない&#x2026; 期待値は最後に Set の要素数が 0 になること.
          </p>

          <p>
            [sourcecode language=&#8221;language&#8221; title=&#8221;&#8221; ]<br /> size is 1<br /> start<br /> I will die<br /> size is 1<br /> [/sourcecode]
          </p>

          <p>
            もう少し調べてみる. 以下を Thread の内部と外に仕込んだ.
          </p>

          <p>
            [sourcecode language=&#8221;java&#8221; title=&#8221;&#8221; ]<br /> System.out.println (this);<br /> System.out.println (this.getClass ());<br /> [/sourcecode]
          </p>

          <p>
            どうも Runnable () クラスの内部と外部では, this を呼んでも別のクラスをさしているようだ.
          </p>

          <p>
            [sourcecode language=&#8221;language&#8221; title=&#8221;&#8221; ]<br /> size is 1<br /> start<br /> A@5df86e79<br /> class A<br /> A$1@5f92b8f5<br /> class A$1<br /> I will die<br /> size is 1<br /> [/sourcecode]
          </p></div> </div> </div> 

          <div id="outline-container-unnumbered-3" class="outline-2">
            <h2 id="unnumbered-3">
              無名クラスに引数を渡す
            </h2>

            <div class="outline-text-2" id="text-unnumbered-3">
              <p>
                this でさす内容が違うならば, this をしなければよいのでは?? ということで, 無名クラスにパラメータを渡す方法をしらべる.
              </p>

              <p>
                どうやら, 無名クラスのなかに, メソッドを定義すればよいようだ.
              </p>

              <ul class="org-ul">
                <li>
                  <a href="http://www58.atwiki.jp/chapati4it/pages/61.html">ちゃぱてぃ商店 IT 部 @ ウィキ &#8211; Java/ サンプル/ 無名クラスにパラメータを渡す</a>
                </li>
              </ul>

              <p>
                ということで以下を変更
              </p>

              <ul class="org-ul">
                <li>
                  無名クラスのなかに, パラメータをうけとる属性を作成
                </li>
                <li>
                  無名クラスのメソッドでパラメータをセットする setter を作成. このメソッドは自分自身 (Runnnable) を返す.
                </li>
                <li>
                  スレッドを起動する前に, パラメータをセットする.
                </li>
              </ul>

              <p>
                [sourcecode language=&#8221;java&#8221; title=&#8221;&#8221; ]<br /> import java.util.HashSet;<br /> import java.util.Set;<br /> import java.util.Collections;
              </p>

              <p>
                public class TimeoutObjectSample {<br /> public static void main (String[] args) {<br /> new B ();<br /> }<br /> }
              </p>

              <p>
                class B {<br /> Set<A> set;</p> 

                <p>
                  public B () {<br /> set = Collections.synchronizedSet ( new HashSet<A>() );<br /> A a = new A (this);</p> 

                  <p>
                    set.add (a);<br /> System.out.println (&#8220;size is &#8221; + set.size ());<br /> a.start ();<br /> }
                  </p>

                  <p>
                    public synchronized Set<A> getSet () {<br /> return set;<br /> }</p> 

                    <p>
                      }
                    </p>

                    <p>
                      class A {<br /> B parent;
                    </p>

                    <p>
                      public A (B parent) {<br /> this.parent = parent;<br /> }
                    </p>

                    <p>
                      void start () {<br /> System.out.println (&#8220;start&#8221;);<br /> System.out.println (this);<br /> System.out.println (this.getClass ());
                    </p>

                    <p>
                      new Thread (new Runnable () {<br /> A a;<br /> int time;
                    </p>

                    <p>
                      public Runnable setParam (A a, int time) {<br /> this.a = a;<br /> this.time = time;<br /> // 自分自身を返す.<br /> return this;<br /> }
                    </p>

                    <p>
                      public void run () {<br /> try{<br /> Thread.sleep (time);<br /> } catch (InterruptedException e){<br /> } finally {<br /> Set<A> set = parent.getSet ();<br /> System.out.println (&#8220;I will die&#8221;);<br /> set.remove (a);<br /> System.out.println (&#8220;size is &#8221; + set.size ());<br /> }<br /> }<br /> }.setParam (this, 1000)<br /> ).start ();<br /> }<br /> }<br /> [/sourcecode]</p> 

                      <p>
                        これでうまくいきました.
                      </p></div> </div>

26 Nov 2014, 13:47

Java でのジェネリックスの使い方まとめ

はじめに

異なる型のオブジェクトを Set に入れる方法を調べた.

Object 型

すべてのクラスの頂点にたつ Object 型を利用すれば, どんな型だっていれることができる.

ジェネリックスを利用しない場合は, Collection は Object 型で代入される.

[sourcecode language=”java” title=””]
class A {
public void show () {
System.out.println ("I’m A");
}
}

class B {
public void show () {
System.out.println ("I’m B");
}
}
public class GenericSample {
public static void main (String[] args) {
HashSet set = new HashSet ();
A a = new A ();
B b = new B ();

set.add (a);
set.add (b);

for (Object x: set) {
if (x instanceof A) {
A xx = (A) x;
xx.show ();
}
if (x instanceof B) {
B xx = (B) x;
xx.show ();
}
}
}
}
[/sourcecode]

欠点は, set に入れるときに Object 型にキャストされるので, メソッド利用時に, 再度 キャストする必要がある.

[sourcecode language=”java” title=””]
for (Object x: set) {
if (x instanceof A) {
A xx = (A) x;
xx.show ();
}
if (x instanceof B) {
B xx = (B) x;
xx.show ();
}
}
[/sourcecode]

ジェネリックス型

利用時にキャストするのが面倒. そんな面倒くささを払拭するのが, Java のジェネリックスという機能.

コンパイル時にのみ型チェックが行われるが, コードとしてキャストをかかなくていいというメリットがある.

ジェネリック利用 共通の親クラス

共通の親クラスを継承させることで,Object の範囲をもう少し狭くする.

[sourcecode language=”java” title=””]
import java.util.HashSet;

public class GenericSample {

public static void main (String[] args) {
HashSet set = new HashSet();
D d = new D ();
E e = new E ();

set.add (d);
set.add (e);

for (C x: set) {
x.show ();
}
}
}

abstract class C {
public abstract void show ();
}

class D extends C {
public void show () {
System.out.println ("I’m D");
}
}

class E extends C {
public void show () {
System.out.println ("I’m E");
}
}
[/sourcecode]

これだと, instanceof やキャストを省略できる.

ジェネリック型を定義する

ジェネリック型を定義してみる.

定義をするためには,

  • <> で囲まれた記号をクラス名の定義につける
  • <> で囲んだ記号で, 型を置き換える.

Example

<div class="outline-text-3" id="text-unnumbered-6">
  <p>
    下の例では, ジェネリックスクラスを自分で定義することで, C,D クラスを E クラス一つで表現している.
  </p>

  <p>
    [sourcecode language=&#8221;java&#8221; title=&#8221;&#8221;]<br /> import java.util.HashSet;<br /> import java.util.Set;
  </p>

  <p>
    public class GenericsSample2 {<br /> public static void main (String[] args) {<br /> C c = new C ();<br /> c.add (1);<br /> System.out.println (c.get ());
  </p>

  <p>
    D d = new D ();<br /> d.add ("Hello");<br /> System.out.println (d.get ());
  </p>

  <p>
    E<Integer> e = new E<Integer>();<br /> e.add(1);<br /> System.out.println(e.get());
  </p>

  <p>
    E<String> f = new E<String>();<br /> f.add("Hello");<br /> System.out.println(f.get());<br /> }<br /> }
  </p>

  <p>
    class C {<br /> private Set<Integer> set = new HashSet<Integer>();
  </p>

  <p>
    void add (Integer i) {<br /> set.add (i);<br /> }
  </p>

  <p>
    Integer get () {<br /> for (Integer i : set) {<br /> return i;<br /> }<br /> return -1;<br /> }<br /> }
  </p>

  <p>
    class D {<br /> private Set<String> set = new HashSet<String>();
  </p>

  <p>
    void add (String str) {<br /> set.add (str);<br /> }
  </p>

  <p>
    String get () {<br /> for (String s : set) {<br /> return s;<br /> }<br /> return null;<br /> }<br /> }
  </p>

  <p>
    class E<T> {<br /> private Set<T> set = new HashSet<T>();
  </p>

  <p>
    void add (T i) {<br /> set.add (i);<br /> }
  </p>

  <p>
    T get () {<br /> for (T i : set) {<br /> set.clear ();<br /> return i;<br /> }<br /> return null;<br /> }<br /> }<br /> [/sourcecode]
  </p>
</div>

ジェネリックスの名前付け

<div class="outline-text-3" id="text-unnumbered-7">
  <p>
    慣例があるようだ.
  </p>

  <ul class="org-ul">
    <li>
      <a href="http://java.keicode.com/lang/generics-naming.php">名前付けルール &#8211; Java 入門</a>
    </li>
  </ul>
</div>

異種コンテナの実装

最後に, Effective Java から, エレガントなジェネリックスの使い方の引用.

[sourcecode language=”java” title=””]
import java.util.Map;
import java.util.HashMap;

public class GenericsSample3 {
public static void main (String[] args) {
Favorites f = new Favorites ();
f.putFavorite (String.class, "Java");
f.putFavorite (Integer.class, 0xcafebebe);

String s = f.getFavorite (String.class);
int i = f.getFavorite (Integer.class);

System.out.println (s + i);
}
}

class Favorites {
private Map, Object> favorites =
new HashMap, Object>();

public void putFavorite (Class type, T instance) {
if (type == null)
throw new NullPointerException ();
favorites.put (type, instance);
}

public T getFavorite (Class type) {
return type.cast (favorites.get (type));
}
}
[/sourcecode]

Environment

  • Java 1.7

25 Nov 2014, 13:47

委譲のまとめと Strategy パターンの実装 (Java)

はじめに

委譲.

よく聞く言葉だが, 実際にどういうものか知らなかったので調べてみた.

Delegation

委譲.あるオブジェクトの操作を一部他のオブジェクトに代替させる手法.

特徴

  • 委譲を行うオブジェクトは委譲先オブジェクトへの参照を持つ
  • 必要に応じてその参照を切り替える事で動作にバリエーションを持たせる事ができる
  • プラグイン機構

コンポジショントデリゲーション

  • 委譲の実現には多くの場合コンポジションを使用する. 委譲は「目的」であり, コンポジションはその「手段」.

参考:

継承との比較

  • 実装の観点では,
  • 抽象クラスはメソッドに対する実装を含むことを許されている.
  • インタフェースはメソッドに対する実装を含むことを許されていない.

  • 機能の観点では,

    • 抽象クラスはある機能の実装を強制する.
    • インタフェースは任意の機能を混ぜ合わせる.
  • 階層化の観点では,

    • 抽象クラスは物事を階層化することに優れる.
    • インタフェースは階層を持たないものをまとめることに優れる.

メリット

  • Java の場合継承は一クラスしかできないが, 委譲なら複数可能
  • 継承なら親クラスのメソッドが全て公開されてしまうが, 委譲なら必要なものだけ公開できる.

デメリット

  • 継承に比べてコードの記述量が多くなる.
  • 継承は何も書かなければ親クラスの機能が使える. 委譲はメソッドの呼び出しを実装しなくてはならない.

  • eclipse では, 右クリック→ソース→委譲メソッドで簡単に作成できる.

  • Ruby には delegation のライブラリがある. Ruby で delegation (委譲) を簡単にする 2 つの方法 - Qiita

参考:

関連する Design Pattern

  • Adapter
  • Proxy
  • Facade
  • State
  • Strategy
  • ほかにもあるかな…

Strategy Pattern

サンプルとして, Gof デザインパターンの Strategy パターンを書いた. 参考:Tricorn Labs » State パターンと Strategy パターンは何が違うのか考える

ここでは, 戦略を別々のクラスに委譲することで, 次々に切り替えている.

動的に A が保持するオブジェクトを切り替えているので, こういう場合は, コンポジションではなくて集約関係というのか な?? (素人の見解)

public class DelegationSample {
    public static void main (String[] args) {
        A x = new A ();

        x.setHuman (new B ());
        x.greeding ();
        x.setHuman (new C ());
        x.greeding ();
    }
}

class A {
    Human a; // 集約

    void setHuman (Human x) {
        a = x;
    }

    void greeding () {
        a.greeding (); // 委譲
    }
}

interface Human {
    void greeding ();
}

class B implements Human {
    public void greeding () {
        System.out.println ("やあ");
    }
}

class C implements Human {
    public void greeding () {
        System.out.println ("オス!");
    }
}

Effective Java から

p101 戦略を表現するために関数オブジェクトを使用する

  • 戦略を現すインタフェースを用意
  • 個々の具象戦略に関してそのインタフェースを実装しているクラスを定義.
    • 具象戦略が一度しか利用されないならば, 無名クラスで作成
    • 繰り返し利用されるならば, public static final の フィールド or static factory method を通じて提供.

24 Nov 2014, 14:25

抽象データ型とドメイン駆動設計の関係について

はじめに

この記事の続きです.

設計とはデータ型を決めること

前回の記事を引用すると,

アプリケーションを設計するということは, まずそのアプリケーションで利用されるデータ型を定義するということ

その後, 自分が定義したデータ型を操作するインタプリタを設計する.

Java をつかっているものの, Java はそれらのデータ型のインタプリタでしかない

オブジェクト指向設計とはなんだろうか?

そんなことを考えていたとき, オブジェクト指向設計の本としてもっとも名高い本, エリック・エバンズのドメイン駆動設計が本屋にあった

思わず衝動買いした.

ドメイン駆動設計

ドメイン駆動設計とは, Eric Evans の提示した設計手法. DDD と略す.

本はこれ.

データ型の設計とは

抽象データ型については前回の記事でまとめた.

抽象データ型もオブジェクトも性質と操作の管理の仕方が異なるだけで, 性質や操作自体は同一だ.

抽象データ型を設計して, 型のインタプリタを作成すること.

DDD でいえば, エンティティと値オブジェクトを決めて, それを操作するサービスや集約, 生成方法を決定すること.

両者はおなじことを言っているように感じた. アプリケーションで扱う型を決めるということは, ドメイン層における, エンティティと値オブジェクトを決めるということ.

これが, とりありず前半部分を読んだ感想だ.

DDD 本の前半まとめ

以下 DDD 本の読書メモ.

とくに, リポジトリの章は, 明日まさに仕事で考えないといけないことなので, とても参考になった.

基本原則 (前書きより)

  • コアドメインに集中すること
  • ドメインの実践者とソフトウェアの実践者による創造的な共同作業を通 じてモデルを探求すること
  • 明示的に境界づけられたコンテキストの内部で, ユビキタス言語を語ること.

基本用語

巻末に用語集がある.

ドメイン

  • 知識, 影響, 活動の領域.
  • アプリケーションが対象とする業務領域.

ユビキタス言語 (p24)

ドメインエキスパートと開発者の間で使う共通言語.

  • モデルを言語の骨格として使用する.
  • チーム内のすべてのコミュニケーションとコードにおいて, 厳格にその言語を用いること.
  • 図, ドキュメント, コード, 会話において, 同一の言語を用いること.

UML

  • UML によって議論に確固とした基盤が与えられる.
  • クラス図と相互作用図がつかいやすい.
  • オブジェクトの名前や関係性を共有できる.
  • オブジェクトの概念, なにをおこなうかははっきり伝えることができない.
  • クラス図の操作名やコミュニケーションでそれとなくは伝えられる. はっきり伝えるためには, 補足的なテキストや会話が必要.
  • 説明のためのモデルはオブジェクトモデルである必要は全くなく, 通常はそうでないほうがよい.

ドキュメント

  • モデルは図ではない.図はコミュニケーションの手段に過ぎない.
  • 設計に関する本質的な詳細は, コードにおいてとらえられる.
  • すでにコードでうまくやっていることを, ドキュメントでもやろうとすべきでない.
  • ドキュメントは活動の役にたたなければならず, 最新の状態を保たなければならない.
  • ドキュメントを最小限にとどめ, その重点をコードと会話の補足に絞る ことで, ドキュメントを常にプロジェクトに結びつけた状態にたもつ.

モデル駆動設計 (P45)

  • 分析モデルと設計ととう二分法を捨て去り, 両方の目的に 使える単一のモデルを探し出す.
  • モデリングと設計のプロセスは, 反復されるただ 1 つのループ.
  • 設計で必要とする用語法と責務の基本的な割り当てをモデルから引き出すこと.
  • 開発は, モデルと設計, コードを単一の活動として改良しつづける, イテレーティブなプロセスとなる.

モデル駆動設計の構成要素 (p65)

レイア化アーキテクチャ (p66)

以下の 4 つに分解される.

  1. UI 層

    ユーザとの相互作用の境界となる層 (Web 層, プレゼンテーション層)

  2. アプリケーション層 (サービス層)

    ドメインオブジェクトを操作することで, ソフトウェアが果たすべき仕事を実現する層. 薄くシンプルにたもち, 仕事はドメイン層のオブジェクトにやらせる.

  3. ドメイン層

    ビジネス上の概念を表現する層.モデル層

  4. インフラストラクチャ層

    上の 3 層を支える技術的な基盤となる層. データベース, 通信など.

エンティティ (参照オブジェクト) (p87)

属性ではなく,連続性と識別性によって定義されるモノ

  • 連続性
    • 状態をもつ.
    • ライフサイクルをもつ.
  • 識別性
    • 一意であることが保証された記号をそえることによって実現できる.
    • ID, 座席番号, 出席番号… システムが生成する.

振る舞いと属性を, 他のオブジェクトに移動できないか検討する. (別のエンティティ, 値オブジェクト, サービス..)

値オブジェクト (p95)

事物の特性を記述するオブジェクト. 概念的な同一性はない.

  • 識別子を持たない (与えてはいけない) 属性にのみ興味がある.
  • オブジェクトは不変でなければならない (fatal)
  • 通例読み出し専用のオブジェクト.
  • Flyweight パターンを用いて共有できる.
  • しばしば, オブジェクト間のメッセージでパラメータとして渡される.

サービス (p103)

  • 操作をおこなう責務をもつ.
  • ソフトウェアが実行すべきことに対応し, 状態には対応しない.
  • オブジェクト自身に操作をさせずに, それぞれごとにオブジェクトの操 作をするものは, しばしばマネージャーと呼ばれる.それは手続的だ.
  • 状態をもたせないこと.
  • 要求に応じてクライアントのために行われるなにか. なので, 名詞よりも動詞として定義される.
  • 操作名がユビキタス言語の一部になること.

モジュール / パッケージ (p108)

  • モデルの意味ある一部.
  • モジュール内は高凝縮, モジュール間は低結合.
  • モジュールは本で言えば章.
  • モジュール名は, ユビキタス言語をつけること. ドメインに関する深い洞察を反映していなければならない.

ドメインオブジェクトのライフサイクル (p122)

集約 (Aggregates) (p123)

  • 関連を最小限にして設計する.
  • モデル内にある参照をカプセル化するための抽象化が集約.
  • 関連するオブジェクトの集まりであり, データを変更するための単位. -> 集約のときに宣言する型は抽象クラスかインタフェースになるのかな?
  • 集約にはルートと境界がある.
    • ルート
  • 集約に含まれている特定の 1 エンティティ.
  • 外部オブジェクトへの参照をもつ.(車がルート, タイヤは違う)
  • グローバルな一貫性をもち, 不定条件をチェックする最終責務をも つ.(リソースの開放処理とか?)
    • 境界 * エンティティと値オブジェクトを集約のなかにまとめ, 各集約の周囲に境界を定義すること.
  • 境界の内部に存在するオブジェクトへのアクセスは, ルートオブジェクトを経由して制御すること.

ファクトリー (p134)

  • オブジェクトや集約全体を生成するのが複雑だったり, 内部構造をさらけ出し過ぎている場合は, 別のオブジェクトに移譲すること.
  • ファクトリーでカプセル化する.
  • 実装を簡単に切り替えられるようにできる.
  • 要求される型によって抽象化する.
  • デザインパターンでいくつかまとまっている
    • ファクトリーメソッド
    • ビルダー
    • アブストラクト・ファクトリー
  • ファクトリの置き場所は,
    • 集約のルートオブジェクトにメソッドを用意する.
    • 他のオブジェクトの生成に密接に関わるオブジェクト.

リポジトリ (p146)

  • オブジェクトを使用するための方法は

    1. 生成する
    2. 関連を巡る
    3. クエリを実行して,
      • 属性に基づいてデータベース内でオブジェクトを見つける
    • オブジェクトの構成要素を見つけて, それを再構築する
  • この第 3 の方法こそがリポジトリ.

  • データベース検索は, グローバルにアクセスすることができて, どんなオブジェクトにも直接到達できる. オブジェクトのネットワークは管理しやすくなる.

  • 開発者は通常, そういう設計の機微についてあまり考えない.

  • 格納されたデータからインスタンスを生成することは, エンティティのライフサイクルの一部. なのでこれを再構築と呼んで, 生成と区別する.

  1. 関連でほとんどの場合は十分!

    • 一時的なオブジェクト (値オブジェクト) は必要ない. ライフサイクルが短く, それを利用するクライアントで生成と破棄がされる.
    • 永続化されりオブジェクトのうちで, 関連を巡ってみつけるほうが便利 なものに対しても, クリエによるアクセスは必要ない. なによりも, 集約内部にあるどのオブジェクトも, ルートから辿る以外の方法でアクセスすることは禁止だ.
    • 永続化された値オブジェクトを見つけるには, それをカプセル化する集約のルートとして機能するエンティティから関 連を巡るのが普通のアプローチ.
  2. どのようなときに検索が必要?

    • オブジェクトの属性に基づいた検索を通じて, グローバルにアクセスできなければならないものもある. そういうアクセスを必要とするのは, 集約のルートのうち 関連を巡って到達しようとする都合の悪いもの.
    • データベースへのアクセス方法はいくつかある
  3. リポジトリの作り方

    • リポジトリは, 特定の型のオブジェクトをすべて概念上の集合として表現する. この定義の集合を通じて, 集約のルートに対するアクセスが提供される.
    • クラアイントがリポジトリに対してオブジェクトを要求する際は, クリエメソッドを使用する.
    • グローバルアクセスを必要とするオブジェクトの各型に対して, あるオブジェクトを生成し, その型のすべてのオブジェクトで構成され るコレクションが, メモリ上にあると錯覚させるようにできるようにすること.
    • 実際に直接的なアクセスを必要とする集約ルートに対してのみ, リポジトリを提供すること.

24 Nov 2014, 02:23

Ruby の win32ole で Windows GUI アプリのキー操作を自動化する

はじめに

Windows 上のアプリをキーボード操作で自動化したいと考えた.

Ruby の win32ole を利用すれば, 実現できそうなので, 調べた.

Win32ole とは

Windows 版の Ruby には, win32ole というライブラリがある.

これを利用すると, Ruby から Windows のいろいろなアプリを操作できる. (Excel,iExplore などなど…)

Windows アプリにキーを送ることができるので, キー操作で完結するアプリならば, 操作を自動化できる, というわけだ.

以前, Excel の操作で win32ole を利用した.以下, 過去記事参照.

今回は, キーボード操作関連の情報をまとめる.

WSHShell を操作

WSHShell とは, Windows のシェル. これを Ruby から制御する.手順は 2 つ.

  • あるウィンドウをアクティブにできる
  • アクティブなウィンドウにキーコードを送る

事前準備

<div class="outline-text-3" id="text-unnumbered-4">
  <p>
    以下の 2 行で, まずは wsh オブジェクト生成.
  </p>

  <p>
    [sourcecode language=&#8221;ruby&#8221; title=&#8221;&#8221; ]<br /> require &#8216;win32ole&#8217;<br /> wsh = WIN32OLE.new (&#8216;Wscript.Shell&#8217;)<br /> [/sourcecode]
  </p>
</div>

プログラム起動

<div class="outline-text-3" id="text-unnumbered-5">
  <p>
    Run メソッドでプログラムを起動できる.
  </p>

  <p>
    [sourcecode language=&#8221;ruby&#8221; title=&#8221;&#8221; ]<br /> wsh.Run (&#8216;notepad.exe&#8217;)<br /> [/sourcecode]
  </p>
</div>

ウィンドウをアクティブにする

<div class="outline-text-3" id="text-unnumbered-6">
  <p>
    AppActivate メソッドで ウィンドウをアクティブにできる.
  </p>

  <p>
    アプリのタイトルを指定する. 成功すると, ture が返る. 失敗すると, false が返る.
  </p>

  <p>
    [sourcecode language=&#8221;ruby&#8221; title=&#8221;&#8221; ]<br /> wsh.AppActivate (&#8216;Title&#8217;)<br /> [/sourcecode]
  </p>
</div>

ウィンドウにキーコードを送る

<div class="outline-text-3" id="text-unnumbered-7">
  <p>
    SendKeys メソッドで ウィンドウにキーを送る.
  </p>

  <p>
    [sourcecode language=&#8221;ruby&#8221; title=&#8221;&#8221; ]<br /> wsh.SendKeys (&#8216;A&#8217;)<br /> [/sourcecode]
  </p>

  <p>
    詳細な SendKey コードはここにある.
  </p>

  <ul class="org-ul">
    <li>
      <a href="http://msdn.microsoft.com/en-us/library/8c6yea83.aspx">SendKeys Method</a>
    </li>
  </ul>
</div>

Sample

notepad

<div class="outline-text-3" id="text-unnumbered-9">
  <p>
    メモ帳起動してなにか書く. Popup メソッドでメッセージ表示.
  </p>

  <p>
    [sourcecode language=&#8221;ruby&#8221; title=&#8221;&#8221; ]<br /> require &#8216;win32ole&#8217;
  </p>

  <p>
    wsh = WIN32OLE.new (&#8216;Wscript.Shell&#8217;)<br /> wsh.Run (&#8216;notepad.exe&#8217;)<br /> wsh.AppActivate (&#8216;無題&#8217;)
  </p>

  <p>
    wsh.SendKeys (&#8216;Hello&#8217;)
  </p>

  <p>
    wsh.Popup (&#8216;Happy Hacking!!&#8217;)<br /> [/sourcecode]
  </p>
</div>

explorer

<div class="outline-text-3" id="text-unnumbered-10">
  <p>
    C:-neraフォルダをコピーして test2 フォルダを作成する.
  </p>

  <p>
    [sourcecode language=&#8221;ruby&#8221; title=&#8221;&#8221; ]<br /> # coding: utf-8<br /> require &#8216;win32ole&#8217;
  </p>

  <p>
    wsh = WIN32OLE.new (&#8216;Wscript.Shell&#8217;)<br /> wsh.Run &#8216;explorer C:\Users\tsu-nera\Desktop&#8217;
  </p>

  <p>
    sleep (3)
  </p>

  <p>
    wsh.AppActivate (&#8216;Desktop&#8217;)
  </p>

  <p>
    # テストフォルダ選択<br /> wsh.SendKeys (&#8216;t&#8217;)
  </p>

  <p>
    sleep (0.5)
  </p>

  <p>
    # コピー & ペースト<br /> wsh.SendKeys (&#8216;^c^v&#8217;)
  </p>

  <p>
    sleep (0.5)
  </p>

  <p>
    # リーネム<br /> wsh.SendKeys (&#8216;{F2}test2{ENTER}&#8217;)
  </p>

  <p>
    # popup<br /> wsh.Popup (&#8216;Copy Success!!&#8217;)<br /> sleep (3)<br /> wsh.SendKeys (&#8216;{ENTER}&#8217;)<br /> [/sourcecode]
  </p>
</div>

23 Nov 2014, 15:29

WordPress の埋め込み gist のスタイルシート (CSS) の設定メモ

はじめに

最近すごく気になってたのだが, ブログでの gist の表示が崩れまくっている ので, 直し方を調べたのでメモする.

以下の過去記事も参照.

CSS の調べ方

要素を調べる

ブラウザのツールを利用して, CSS の要素を調べる.

  • Chrome ならばディベロッパーツール,
  • firefox ならば右クリックから要素を検索

編集画面で該当箇所の css に辿り着いたら, そこを編集する. すると, リアルタイムで変更が確認できる.

class=“gist” class”gist-file” で囲まれている

調べてみると, gist では, <div class=“gist”> などで囲まれていることがわかる.

以下のような StyleSheet に追加する.

/* for gist */
.gist {
    font-size: 16px;
}
.gist-file div{
    background-color: black!important;
}

.gist-file .pl-vo{
    color: white!important;
}

.gist-file .highlight{
    color: white!important;
}

BookMarks

23 Nov 2014, 13:14

データ抽象と抽象データ型 (ADT) について調べたまとめ (Java)

はじめに

仕事の開発プロジェクトのメンバ (正確にはメンバではなくてアドバイザー) でこわーい人がいて,毎日のようにおびやかされてビクビクしている.

その人が書いたクラス図の意味がわからなかったから質問しにいったときのお話.

やりとり

<div class="outline-text-3" id="text-unnumbered-2">
  <p>
    (hoge さん) 「このクラスがなにを現しているか, そもそもわかってる?? 」
  </p>

  <p>
    (Me) (わかっていないから質問をしにいった)
  </p>

  <p>
    (Me) 「データとそれを扱うための便利な操作をまとめたクラスですか? 」
  </p>

  <p>
    (hoge さん) 「それって, ただオブジェクト指向の一般論を言っているだけでは? 」
  </p>

  <p>
    (Me) (にが笑い&#x2026;)
  </p>

  <p>
    (hoge さん) 「わかってないのに, わかったふりをしているよね? 」
  </p>

  <p>
    (hoge さん) 「便利な操作ってなに? そんなことだから, いつも考え方が手続的なんだ!! 」
  </p>

  <p>
    そんなこんなで, 今回もひどい目にあい, あたくしは週末に心療内科にいって坑うつ剤を増量してもらうはめになった.
  </p>
</div>

Answer

<div class="outline-text-3" id="text-unnumbered-3">
  <p>
    その人のいうことには,
  </p>

  <p>
    「このクラスは, アプリケーションのためのデータ型. アプリケーションのベースになるもの. Integer 型や String 型と同じようなもの. 」
  </p>

  <p>
    「アプリケーションを設計するということは, まずそのアプリケーションで利用される データ型を定義するということからはじめる.」
  </p>

  <p>
    「その後, 自分が定義したデータ型を操作するインタプリタを設計する. Java をつかっているものの, Java はそれらのデータ型のインタプリタでしかない」
  </p>

  <p>
    だそうだ.というわけで, 今回は抽象データ型について調べてみた.
  </p>

  <p>
    情報元は, Wikipedia だったり, CPMCP 本だったり.
  </p>
</div>

データ型とは

互いに関係する値の集合.

大きく, 2 種類に分けられる.

基本型は, よく知っているので, 今回は抽象データ型に注目.

抽象データ型とは

  • 自身で定義した型.
  • 状態を持たない.
  • Abstract Data Type (ADT) という.
  • 値の集合とそれらに関係する操作の集合, それぞれ別々に保持しているもの. (別々というところが Object の違い)

ラッパー

<div class="outline-text-4" id="text-unnumbered-6">
  <p>
    値の集合に直接アクセスさせないための操作.(CPMCP p210)
  </p>

  <ul class="org-ul">
    <li>
      値を安全に保持するためには, 鍵 (key) を利用して (包む) 操作を追加する.
    </li>
  </ul>

  <p>
    [sourcecode language=&#8221;bash&#8221; title=&#8221;&#8221;]<br /> Key={NewName}<br /> SS={Chunk.new w (Key:S)}<br /> [/sourcecode]
  </p>

  <p>
    包み, ほどきを行うデータ抽象をラッパーと定義する.
  </p>

  <p>
    [sourcecode language=&#8221;bash&#8221; title=&#8221;&#8221;]<br /> proc {NewWrapper ?Wrap ?Unwrap}<br /> Key={NewName} in<br /> fun {Wrap X}<br /> {Chunk.new w{Key:X}}<br /> end<br /> fun {Unwrap X}<br /> try W.Key catch _ then raise error (unwrap (W)) end end<br /> end<br /> end<br /> [/sourcecode]
  </p>

  <p>
    以下のように, Wrap, Unwrap する.
  </p>

  <p>
    [sourcecode language=&#8221;bash&#8221; title=&#8221;&#8221;]<br /> S={a b c}<br /> SS={Wrap S}<br /> S={Unwrap SS}<br /> [/sourcecode]
  </p>
</div>

データ抽象 (Data Abstraction)

データを抽象的に使う, 使い方.実装にとらわれずにデータを使うこと. インタフェースと呼ばれる規則にしたがって使用される具体化の集合.

データ抽象を型 (Type) といって済ますこともある. 抽象データ型 (ADT) は, 特殊なデータ抽象. 値の集合と, それに関する操作の集合.(CPMCP p431)

Data Abstruction は 操作が値にバインディングされているかいなかで, 2 つの種類に分けられる.

  • Abstruct Data Type (ADT) 値と操作をベツベツに保持する
  • Object 値と操作を一緒に保持する.

オブジェクト

<div class="outline-text-3" id="text-unnumbered-8">
  <p>
    値と操作をひとつのまとまりとしたもの.
  </p>

  <p>
    現在オブジェクト指向言語と呼ばれているものは,実際には,
  </p>

  <ul class="org-ul">
    <li>
      Abstruct Data Type (Java Integer 型)
    </li>
    <li>
      オブジェクト (Java Object 型)
    </li>
  </ul>

  <p>
    の 2 つを合わせもっている.
  </p>

  <p>
    その意味で, オブジェクト指向言語と言うよりは, 抽象データ言語というほうが正しい.
  </p>
</div>

クラス

<div class="outline-text-3" id="text-unnumbered-9">
  <p>
    抽象データからなるデータ構造.
  </p>

  <p>
    属性とメソッドはレコードデータ構造によって管理されているだけ.
  </p>

  <p>
    Class とは, Pair ( attrs[属性の集合] : methods[メソッドの集合]) )
  </p>

  <p>
    Class の 生成 (new) メソッドで オブジェクトが生成される.(インスタンス化)
  </p>

  <p>
    Class という概念によって, オブジェクトの&#8221;宣言&#8221;と&#8221;生成 (new)&#8221;を分離する.
  </p>
</div>

実例

オブジェクト指向における, メソッドの動的ディスパッチを自力で実装. なんてめんどいんだ.

本来ならば, Operation クラスで保持するものは, String ではなくてクロージャだけど, Java7 では実現できない.

hoge さんから提示されたクラス図も, 大体はこんな感じで, HashMap に値やらメソッドやらを保持していた.

[sourcecode language=”java” title=””]
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class ADTSample {
public static void main (String[] args) throws IllegalAccessException,
IllegalArgumentException, InvocationTargetException,
NoSuchMethodException, SecurityException {
ObjectSample obj = new ObjectSample ();
System.out.println (obj.getAttr1 () + " " + obj.getAttr2 ());

ObjectSample2 obj2 = new ObjectSample2 ();
System.out.println (obj2.call (Key.NUM) + " " + obj2.call (Key.STRING));
}
}

class ObjectSample {
int attr1 = 3;
String attr2 = "hello";

public int getAttr1 () {
return attr1;
}

public String getAttr2 () {
return attr2;
}

public void setAttr2 (String attr2) {
this.attr2 = attr2;
}
}

enum Type {
INT,
STRING
}

enum Key {
NUM,
STRING
}

class ObjectSample2 {
private Map attrs = new HashMap();
private Map methods = new HashMap();

public ObjectSample2 () {
// Attributes
attrs.put (Key.NUM, new Attribute (3, Type.INT));
attrs.put (Key.STRING, new Attribute ("hello", Type.STRING));

// Operations
methods.put (Key.NUM, new Operation ("getAttr1"));
methods.put (Key.STRING, new Operation ("getAttr2"));
}

public Object call (Key key) throws IllegalAccessException,
IllegalArgumentException, InvocationTargetException,
NoSuchMethodException, SecurityException {

Operation ope = methods.get (key);
Method method = this.getClass ().getMethod (ope.method, Key.class);
return method.invoke (this, key);
}

public Object getAttr1 (Key key) {
Attribute attr = attrs.get (key);
return attr.value;
}

public Object getAttr2 (Key key) {
Attribute attr = attrs.get (key);
return attr.value;
}
}

class Attribute {
Object value;
Type type;

public Attribute (Object value, Type type) {
this.value = value;
this.type = type;
}
}

class Operation {
String method;

public Operation (String method) {
this.method = method;
}
}
[/sourcecode]

23 Nov 2014, 06:35

Windows での コマンドラインからコピーするコマンドまとめ (xcopy, robocopy, copy)

はじめに

コマンドプロンプトからフォルダのコピーがしたかったので, 調べてみた.

Windows 標準コピーコマンド

Windows8 には, 標準で以下のコマンドが利用できる.

  • copy
  • xcopy
  • robocopy

copy

<div class="outline-text-3" id="text-2-1">
  <p>
    Windows 標準のファイルコピーコマンド.
  </p>

  <ul class="org-ul">
    <li>
      <a href="http://www.k-tanaka.net/cmd/copy.php">コマンドプロンプト copy &#8211; ファイルをコピーする</a>
    </li>
  </ul>
</div>

xcopy

<div class="outline-text-3" id="text-2-2">
  <p>
    copy の改良版. copy よりも高機能.
  </p>

  <ul class="org-ul">
    <li>
      <a href="http://www.k-tanaka.net/cmd/xcopy.php">コマンドプロンプト xcopy &#8211; ファイルをディレクトリ構造ごとコピーする</a>
    </li>
  </ul>

  <p>
    ディレクトリツリーごとコピーできるところが, copy との最大の違い. xcopy があれば, copy はいらない.
  </p>

  <p>
    copy は内部コマンド, xcopy は外部コマンド.
  </p>

  <p>
    [sourcecode language=&#8221;bash&#8221; title=&#8221;&#8221;]<br /> xcopy /e "C:\Users\tsu-nera\Desktop\test" "\\192.168.100.100\共有"<br /> [/sourcecode]
  </p>
</div>

robocopy

<div class="outline-text-3" id="text-2-3">
  <p>
    xcopy よりも高機能なコマンド. リモート間のフォルダ同期ができる. バックアップならば, robocpy が適している.
  </p>

  <ul class="org-ul">
    <li>
      <a href="http://www.atmarkit.co.jp/ait/articles/0704/20/news130.html">Windows TIPS:robocopy でフォルダをバックアップ/ 同期させる &#8211; @ IT</a>
    </li>
  </ul>
</div>

速度について

xcopy と robocopy

<div class="outline-text-3" id="text-3-1">
  <p>
    比較動画をみつけた. robocopy の勝利.
  </p>

  <p>
    <iframe width="420" height="315" src="//www.youtube.com/embed/1y7vmIvK2z8" frameborder="0" allowfullscreen></iframe> </div> </div> 

    <div id="outline-container-sec-3-2" class="outline-3">
      <h3 id="sec-3-2">
        Explore での手動コピーとの違い
      </h3>

      <div class="outline-text-3" id="text-3-2">
        <p>
          調べてみると, xcopy のほうが手動コピーよりも早いらしい.
        </p>

        <ul class="org-ul">
          <li>
            <a href="http://okwave.jp/qa/q6547486.html">通常コピーと CMD でコピー速度の差の理由は? 【 OKWave 】</a>
          </li>
        </ul>

        <p>
          ちなみに, explore.exe にもコマンドラインオブションはある. コマンドプロンプトから指定したフォルダを開くことがてきる. コピーや移動はできないみたい.
        </p>

        <ul class="org-ul">
          <li>
            <a href="http://support.microsoft.com/kb/152457/ja">Windows エクスプローラのコマンドライン オプション</a>
          </li>
        </ul>
      </div>
    </div>

    <div id="outline-container-sec-3-3" class="outline-3">
      <h3 id="sec-3-3">
        FastCopy
      </h3>

      <div class="outline-text-3" id="text-3-3">
        <p>
          ためしていないけれども, FastCopy というものがあるらしい. なんでも, robocopy, xcopy よりも高速とか.
        </p>

        <ul class="org-ul">
          <li>
            <a href="http://www.se-support.com/server/fileserver-copy.html">高速コピーツール「 FastCopy 」はホントに早かった! ファイルサーバー移行テスト</a>
          </li>
        </ul>
      </div>
    </div></div> 

    <div id="outline-container-sec-4" class="outline-2">
      <h2 id="sec-4">
        おまけ
      </h2>

      <div class="outline-text-2" id="text-4">
        <p>
          ダミー用データ作成.以下を参考に .
        </p>

        <ul class="org-ul">
          <li>
            <a href="http://www.atmarkit.co.jp/ait/articles/0209/28/news002.html">Windows TIPS:巨大なサイズのファイルを簡単に作る方法 &#8211; @ IT</a>
          </li>
        </ul>

        <p>
          [sourcecode language=&#8221;bash&#8221; title=&#8221;&#8221;]<br /> # 1KB のファイル作成.<br /> fsutil file createnew 1K_test 1024
        </p>

        <p>
          # 1MB のファイル作成.<br /> fsutil file createnew 1M_test 1048576
        </p>

        <p>
          # 1GB のファイル作成.<br /> fsutil file createnew 1G_test 1073741824<br /> [/sourcecode]
        </p>
      </div>
    </div>

19 Nov 2014, 15:15

Java で TreeSet と Comparator を実装した

はじめに

Java で, 順序づけをした集合をイテレーティブに処理したい.

ちなみに, PriorityQueue では, 実現できなかった…

TreeSet

SortedSet, TreeSet を利用する.

SortedSet はインタフェース, TreeSet は クラスという違いがある.

Comparator

順序をつけるために java.util.Comparator インタフェースを利用する. これは,コレクションの順序づけをおこなうための比較関数,compare をもつ.

以下の記事が詳しい.

具体例

優先度をもつ以下のようなオブジェクトを TreeSet に格納することを考える.

class MyClass {
    private char a;
    private int priority;

    public MyClass (char a, int priority) {
        this.a = a;
        this.priority = priority;
    }

    public int getPriority () {
        return priority;
    }

    public String toString () {
        return "char: " + a + " priority: " + priority;
    }
}

まずは, Comparator を作成する.

import java.util.Comparator;

class MyComparator implements Comparator {
    @Override
    public int compare (Object arg0, Object arg1) {
        MyClass x = (MyClass) arg0;
        MyClass y = (MyClass) arg1;

        int xp = x.getPriority ();
        int yp = y.getPriority ();      

        if (xp < yp) {
            return 1;
        } else if (xp > yp) {
            return -1;
        } else{
            return 0;
        }
    }
}

最後に TreeSet の実装.

import java.util.TreeSet;

public class SortedSetSample {
    public static void main (String[] args) {
        MyClass A = new MyClass ('a', 3);       
        MyClass B = new MyClass ('b', 1);
        MyClass C = new MyClass ('c', 2);

        TreeSet<MyClass> set = new TreeSet<MyClass>(new MyComparator ());

        set.add (A);
        set.add (B);
        set.add (C);

        for (MyClass obj: set) {
            System.out.println (obj);
        }
    }
}

実行結果

char: a priority: 3
char: c priority: 2
char: b priority: 1

Full Code

import java.util.Comparator;
import java.util.TreeSet;

public class SortedSetSample {
    public static void main (String[] args) {
        MyClass A = new MyClass ('a', 3);       
        MyClass B = new MyClass ('b', 1);
        MyClass C = new MyClass ('c', 2);

        TreeSet<MyClass> set = new TreeSet<MyClass>(new MyComparator ());

        set.add (A);
        set.add (B);
        set.add (C);

        for (MyClass obj: set) {
            System.out.println (obj);
        }
    }
}

class MyComparator implements Comparator {
    @Override
    public int compare (Object arg0, Object arg1) {
        MyClass x = (MyClass) arg0;
        MyClass y = (MyClass) arg1;

        int xp = x.getPriority ();
        int yp = y.getPriority ();      

        if (xp < yp) {
            return 1;
        } else if (xp > yp) {
            return -1;
        } else{
            return 0;
        }
    }
}

class MyClass {
    private char a;
    private int priority;

    public MyClass (char a, int priority) {
        this.a = a;
        this.priority = priority;
    }

    public int getPriority () {
        return priority;
    }

    public String toString () {
        return "char: " + a + " priority: " + priority;
    }
}

Special Thanks