Words of the Day – Sunday March 22, 2009

18. Why did they move over for elderly person in the train.
19. This program takes up so much memory resource.

Posted in Words of the Day | Tagged , | Leave a comment

Note of the Day – 2009-03-22

1. 主なデータの管理・取り出し方法

  1. LIFO (Last-In First-Out): キューなどに使われる。
  2. FIFO (First-In First-Out): スタック。再帰的な処理をする際、実行中の状態を保存しておく為にも使われる。
  3. LFU (Least Frequently Used): 参照頻度が最も少ないものを取り出す。
  4. LRU (Least Recently Used): 未使用時間が最も長いものを取り出す。

2. 多態性 (Polymorphism ⇔ Mono-morphism: 単態性) : 同じ名前のクラス(型変数)でも格納されているインスタンスによって違う振る舞いをすること。Java記述言語仕様で具体的に実現する場合は、以下の3通りが考えられる。

  1. 抽象メソッドAが定義されたインターフェイスを実装した二つのクラスは、そのインターフェイス型の変数にインスタンスを格納し、それぞれ実装されたメソッドAを実行すること。
  2. 基底クラスIのメソッドBを派生クラスJでオーバーライドし、基底クラス型の変数に派生クラス型のインスタンスを格納し、IのメソッドB経由でJでオーバーライドされたメソッドを実行すること。
  3. ↑のを抽象クラスに置き換えても可。

例: Simple Factory – インスタンスの生成方法を任せる – Yukun’s Blog

3. OSI (Open Source Initiative)はOpen Sourse の定義としてOSD (Open Source Definition)を定めている。派生著作物に元のソフトウェアとは異なる名前やバージョンをつけるように要請することができる。

オープンソースの定義 (http://www.opensource.jp/osd/osd-japanese.html)

  1. 再頒布の自由
  2. ソースコード(を含んでいなければならない)
  3. 派生ソフトウェア(を元のソフトウェアと同じライセンスで頒布することを許可しなければならない)
  4. 作者のソースコードの完全性(integrity)
  5. 個人やグループに対する差別の禁止
  6. 利用する分野に対する差別の禁止
  7. ライセンスの分配
  8. 特定製品でのみ有効なライセンスの禁止
  9. 他のソフトウェアを制限するライセンスの禁止
  10. ライセンスは技術中立的でなければならない。

4. 主なシステム開発手法

  • ウォータフォールモデル: 上流→下流工程順。進捗管理と資源分配は簡単だが、工程の後戻りと仕様変更が困難。頻繁に後戻りが発生する欠点もあり。
  • エボリューショナルモデル: 最初にシステム全体のプロトタイプモデルを作成して、それをバージョンアップさせていくモデル。レビューと仕様変更は容易だが進捗管理が困難。
  • スパイラルモデル: ウォータフォールモデルとエボリューショナルモデルを融合したモデル。システムをいつかに分割し、その部分ごとに設計→プロトタイプ作成→評価を繰り返す。仕様変更はしやすい。
  • インクリメンタルモデル: 共同開発可能でかつ独立したサブシステムに機能を分割し、それぞれを同時に開発、段階的にリリースしていく。利点は全ての機能がそろっていなくても最初のリリースからシステム全体の動作を確認できる。

5. DFD (Data Flow Diagram)で用いられる図形要素は、データの源泉(と吸収)、プロセス、データストア、データフローなどがある。ERD (Entity Relationship Diagram: E-R図)は関連、実態、属性などがある。
参考: データフロー図 – Wikipedia実体関連モデル – Wikipedia

6. ホワイトボックステストでの4つの網羅

  1. 命令網羅
  2. 判定条件網羅
  3. 分岐網羅
  4. 複数条件網羅

7. 多重プログラミングでは演算処理が中心のプログラム同士だと、CPUの使用率が上がるためシステム全体のスループットは低下する。

8. ある作業工程Aの最遅開始日はクリティカルパスから工程Aの所要日数分だけ前倒しした日程である。それ以降は全体の日程に影響を与える(クリティカルパス自体が伸びる)。

9. ガントチャートは縦軸:人員、作業内容で横軸:時間の図で、工程管理に用いられる。各作業の開始・終了納期や進捗状況の把握が容易。しかし、作業の遅延による影響はわかりずらく、将来の予測も立て難い。作業の相互関係やマイルストーンの把握には向かない。
Gantt Chart
参考:ガントチャート – Wikipedia

Posted in Note of the Day | Tagged , , , , | Leave a comment

Words of the Day – Saturday March 21, 2009

12. That blog article combines prose with poetry.
13. The up-to-date patch of secrity came out last week.
14. Do you know the well-known fairy tale as a fable.
15. He feels the generation gap toward a contemporary.
16. I use next to nothing about this function.
17. At times I encounter the fabulose sculpture in the museum.

Posted in Words of the Day | Tagged , | Leave a comment

Words of the Day – Friday March 20, 2009

3. We are fair in terms of drawing a card at random in a sense.
4. He stood on leaning against the wall.
5. A girl passed by me giving off a subtle scent of powder smoke.
6. It reminded me of the awful case.
7. I was so beside myself that I’m soaked of sweat.
8. Ichiro is the mental pillar of Japan.
9. The candy that I receive tastes terrific.
10. Regardless of wearing a mask, this room stinks.
11. Do you know such perfume that includes the potential harmful effect that can scarcely tell fact from fiction.

Posted in Words of the Day | Tagged , | Leave a comment

Excel VBA: Hello Worldと変数、配列の宣言

ポツポツ使う場面が増えてきたので、備忘録代わりにまとめていこうかな(気が向いたときに)。

VBAでHello World

メニューバーからツール→マクロ→Visual Basic Editor(Alt+F11)をクリックするとエディタが起動します。最初は何もファイルが開かれていないと思うので、まず、メニューバーから挿入→標準モジュールをクリックして新規作成し、試しに以下のコードを打ち込んで実行してみます。

Sub helloWorld()
    MsgBox "Hello, VBA"
End Sub

入力し終わったらメニューの実行→Sub/ユーザー フォームの実行(F5)をクリックするとスクリプトが実行されます。結果は下図のようになります。
vba_hello_world
ダイアログボックス内に文字列が表示されていますね。仮に下記のようにした場合は、

Sub helloWorld()
    MsgBox "Hello, VBA"
    MsgBox "Hello, Excel"
End Sub

一つ目の”Hello, VBA”のダイアログのOKを押した後、”Hello, Excel”のダイアログが表示されます。どうやらMsgBox関数はブロック関数みたい。

変数の宣言 – Dim

Sub varTest()
    Dim num1 As Integer
    Dim str1 As String
    Dim num2 As Integer, str2 As String

    num1 = 10
    str1 = "文字列1"

    MsgBox num1 & " " & str1
    MsgBox num2 & " " & str2, vbInformation, "デバッグプリント"
End Sub

実行結果は
vba_var01
vba_var02

変数宣言の一般式は

Dim <変数名> As <型>

のようにDim~Asステートメントを用います。

また、MsgBox関数のvbinformationを指定することで情報メッセージアイコンを表示します。ちなみに、出力する複数の文字列の連結は「&」を用います。

定数の宣言 – Const

Const <定数名> As <型> = <値>

変数宣言と似てますね。異なるところは、DimがConstに変わり、宣言と値の初期化を同時に行うことですかね。変数も値の初期化は可能ですが、それは任意です。

オブジェクトの参照を変数に格納 – Set

オブジェクトの参照を代入する際にはSetステートメントを使用します。以下のコードは1つ目のワークシート名を表示しています。

Sub objectTest()
    Dim tmpSheet As Worksheet
    Set tmpSheet = Worksheets(1)
    MsgBox tmpSheet.Name, vbInformation
End Sub

実行結果は
vba_var_set01
一般式は

Set <オブジェクト型変数> = <オブジェクト>

コンパイルエラー、「SubまたはFunctionが定義されていません」の原因

大抵ミスタイプです。Worksheets(1)と打つところをWorksheet(1)としてしまうとか。変数宣言のミスでもデフォルトでは「SubまたはFunctionが~」と出力されるので注意。

配列の宣言

Dim <配列名>(<要素数>) As <型>

Sub objectTest()
    Dim arr(3) As Integer
    arr(0) = 99
    MsgBox arr(0)
End Sub

ダイアログには99が表示されます。配列の添え字は0から数えますが、下記の文をモジュールの宣言セクションに書くことで1から数えられます。

Option Base 1

Option Base 1

Sub objectTest()
    Dim arr(3) As Integer
    arr(1) = 99
    MsgBox arr(1)
End Sub

実行結果は同じく99です。

Posted in Excel VBA | Tagged , | Leave a comment

Words of the Day – Thursday March 19, 2009

1. I can assure you that I will make the new application.
2. Let go of my redundant emotions.

Posted in Words of the Day | Tagged , | Leave a comment

Java: イベント駆動によるModelとViewの分離 – Observer パターン

よくGUIやWebアプリの簡単なサンプルソースなどは、UIとアプリケーションのロジックが同じクラスまたはメソッドに書かれている場合が多いです。それはそのサンプルがある特定の機能や関数の紹介の為に簡潔に書いているのですが、仮にいざそのソースを元にアプリを作りこんで機能の追加を行っていくとUIとアプリのロジックは分離したほうが保守・拡張と共に行いやすいです。

下記のプログラムは1秒毎に数値をカウントし、それを2進数と10進数でGUI上のラベルに出力する機能をモデルとビューに分けています。すなわち、数値のカウントをするモデルと数値をUIに表示するビューに。(いくつかの言語ではGUIの部品としてタイマーがあるようですが。。)

実行結果

count_timer01

クラス図

countmodel_view_class

インスタンスの生成はコンストラクタで行うのがいいのですが、はしょっています。さて、これまでに何らかのフレームワークを使っていた方には上クラス図はMVCの説明図として見慣れているかもしれません。今回ModelとViewを繋ぐControllerの役割はCountListenerが担っています(下記コードではCountChangeEvent経由でModelインスタンスを渡すのみですが)。

処理手順

ビュー側で自身のインスタンスをモデルに登録し(モデル.addCountListener(ビュー))、モデルのデータが更新された場合、モデル→ビューへイベントを送出。イベント内部にモデルのデータがあり、そのデータでビューがUIを更新します。イベントの発生順序等は下図のシーケンス図のようになります。

シーケンス図

countmodel_view_sequence

無限ループに注意

ビューを更新するイベントリスナーのメソッド(ここではcountChanged())で再度モデルのプロパティ変更メソッド(ここではsetCount())を用いると、再度イベント通知処理(notifyToListeners())が発生することで、無限ループになるので注意が必要です。

ビューの追加手順

ビューを追加する際の手順は、ビューのインスタンスをモデルのリスナーに登録し(addCountListener())、ビュー自身がリスナーのメソッドを実装することで(countChanged())、モデルからのイベントを受け取ることが出来ます。

そういえば最近はIDEの方でバインド設定したり、ObservableList等があるのであまり意識することがなくなってきたなぁ。

ソースコード

import java.awt.Container;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;

class CountView extends JFrame implements CountListener{

	private final JLabel binaryLabel = new JLabel("0");
	private final JLabel decimalLabel = new JLabel("0");
	private CountModel cModel = new CountModel(0);

	public static void main(String[] args) {
		new CountView();
	}

	public CountView() {
		super("Counter");
		Container c = getContentPane();
		c.setLayout(new GridLayout(2, 2));
		c.add(new JLabel(" 2進数:"));
		c.add(binaryLabel);
		c.add(new JLabel("10進数:"));
		c.add(decimalLabel);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		cModel.addCountListener(this); // ModelにViewを登録

		pack();
		setVisible(true);
	}

	public void countChanged(CountChangeEvent e) {
		if (e.getSource() == cModel) {
			binaryLabel.setText(Integer.toString(cModel.getCount(), 2));
			decimalLabel.setText(Integer.toString(cModel.getCount(), 10));
		}
	}
}
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

/**
 * カウントするModel
 */
public class CountModel {

	private int count;
	private final List<CountListener> listeners = new ArrayList<CountListener>();
	private Timer t = new Timer("Count Timer", false);

	CountModel(int i) {
		count = i;
		t.scheduleAtFixedRate(new CountTime(), 0, 1000);
	}

	// Viewを登録
	public void addCountListener(CountListener listener) {
		listeners.add(listener);
	}

	public int getCount() {
		return count;
	}

	public void setCount(int i) {
		count = i;
		notifyToListeners();
	}

	// Viewへの通知
	private void notifyToListeners() {
		for (CountListener listener : listeners) {
			listener.countChanged(new CountChangeEvent(this));
		}
	}

	class CountTime extends TimerTask {
		@Override
		public void run() {
			setCount(getCount() + 1);
		}
	}
}
/**
 * View側で実装する(Model側から呼び出し)
 */
public interface CountListener {
	public void countChanged(CountChangeEvent e);
}

/**
 * 通知内容を表すイベント(Modelが生成しViewが受け取る)
 */
public class CountChangeEvent {
	private final CountModel source;

	public CountChangeEvent(CountModel count) {
		this.source = count;
	}

	public CountModel getSource() {
		return source;
	}
}
Posted in Java | Tagged , , , , | Leave a comment

Java, デザインパターン: Simple Factory – インスタンスの生成方法を任せる

以前デザインパターンの理解の確認がてら簡単なコードを書いていたので投稿してみます。リファクタリングの前後を省いているので初見ではパターンのメリットと適応基準が見えにくく、またサンプルのテーマ設定が良くなかったのでイマイチ説明し難い(反省)。今回のようなToyコードみたいなのはたまに書くのですが、Blog記事としてまとめるのが手間で大抵HDDの片隅に眠ってしまうのですが、今後はとりあえず上げていこうかと思います。説明などは隙をみて書き足していく感じでまず投稿、みたいな。ただ、そればっかりだと後で自分が読んだときに分からなくなるので、ほどほどにしよう。

クラス図

simple_factory_classes

文字列の分割プログラム。

入力: クラス名+<区切り文字>+メソッド名の文字列
出力: その文字列の分割結果が格納されたインスタンス(Namerクラス)。

文字列の形式が”<クラス名>#<メソッド名>”か”<クラス名>.<メソッド名>”によって、すなわち区切り文字によって分割処理のメソッドの内容が変わるので、その違いを派生クラスでオーバーライドして定義したメソッドで吸収しようというもの。

これによる利点はMain側が分割対象の文字列の形式を意識しなくてよいこと。単にNameFactory#getNamer()に渡すだけ。文字列の形式が2つの内のどちらで、どのクラスに処理を任せるかの処理はgetNamer()が行う。これによって、仮に文字列の形式を増やす場合に修正するのはgetNamer()のifブロック、追加するのは新しい派生クラス。

ソースコード

public class Main {

    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        NameFactory nameFactory = new NameFactory();
        Namer namer;
        namer = nameFactory.getNamer("String#indexOf()");
        printName(namer);
        namer = nameFactory.getNamer("ArrayList.get()");
        printName(namer);
        namer = nameFactory.getNamer("Thread#run()");
        printName(namer);
    }

    private void printName(Namer namer) {
        System.out.println("Class  Name: " + namer.className);
        System.out.println("Method Name: " + namer.methodName);
    }

}

public class NameFactory {
    // 区切り文字の種類によって、処理する派生クラスを決める
    public Namer getNamer(String input) {
        if (input.indexOf(".") > 0)
            return new PeriodNamer(input);
        else if (input.indexOf("#") > 0)
            return new SharpNamer(input);
        return null;
    }
}

public class Namer {

    protected String className;
    protected String methodName;

    public String getClassName() {
        return className;
    }

    public String getMethodName() {
        return methodName;
    }
}

public class SharpNamer extends Namer {
    // 「#」で名前を区切る
    public SharpNamer(String str) {
        int i = str.lastIndexOf("#");
        if (i > 0) {
            className = str.substring(0, i); // (beginIndex, endIndex)
            methodName = str.substring(i + 1); // (beginIndex)
        } else {
            className = "";
            methodName = str;
        }
    }
}

public class PeriodNamer extends Namer {
    // 「.」で名前を区切る
    public PeriodNamer(String str) {
        int i = str.lastIndexOf(".");
        if (i > 0) {
            className = str.substring(0, i); // (beginIndex, endIndex)
            methodName = str.substring(i + 1); // (beginIndex)
        } else {
            className = "";
            methodName = str;
        }
    }
}

実行結果

Class  Name: String
Method Name: indexOf()
Class  Name: ArrayList
Method Name: get()
Class  Name: Thread
Method Name: run()

書いた後ふと考えたのですが、これ100形式だと100派生クラスで、if-elseブロックもえらいことになるなぁ。こういう時、現時点では思考停止してしまうので、今月の課題。

今後はなるべく制作中のアプリの中での問題かそれに関わるもの、絡められるものを取り上げていきたい。

Posted in Java | Tagged , , | 1 Comment

Java, JSP: 現在時刻が指定期間内か判定する – GregorianCalendar#before、after

日時を扱うクラスはDateとGregorianCalendarがありますが、Sunは後者を推奨しているようです。実際GregorianCalendarのほうが扱いやすいです。下のサンプルは、現在時刻が指定した期間内か否かを判定するものです。

ソースコード

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@page import="java.util.*" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">
<html>
  <%!
    final int MONTH_OFFSET = 1;

    String showTime(Calendar cal) {
      String str;
      str = cal.get(Calendar.YEAR) + "/"
        + (cal.get(Calendar.MONTH) + MONTH_OFFSET)  + "/"
        + cal.get(Calendar.DATE) + " "
        + cal.get(Calendar.HOUR) + ":"
        + cal.get(Calendar.MINUTE);
      return str;
    }

    boolean isPeriod(Calendar start, Calendar end) {
      Calendar cur = Calendar.getInstance();
      return cur.after(start) && cur.before(end);
    }
  %>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Date Comparison</title>
    </head>
    <body>
        <h1>JSP Date Comparison</h1>
    <%
      // (year, month, date, hour, minute) monthの範囲は0-11で1月は0
      Calendar startTime = new GregorianCalendar(2009, 2 - MONTH_OFFSET, 23, 21, 0);
      Calendar endTime = new GregorianCalendar(2009, 2 - MONTH_OFFSET, 23, 21, 10);

      out.println("開始時刻: " + showTime(startTime) + "<br />");
      out.println("終了時刻: " + showTime(endTime) + "<br />");

      if (isPeriod(startTime, endTime)) {
        out.println("現時刻は指定期間「内」");
      } else {
        out.println("現時刻は指定期間「外」");
      }
    %>
    </body>
</html>

日時の比較はGregorianCalendar#after、beforeメソッド以外にint compareTo(Calendar cal)等もあります。
実際に使う際、期間を指定するGregorianCalendarのコンストラクタの引数データは他の入力から受け取るようにします。

実行結果例

本日の21:05に計ると…

JSP Date Comparison
開始時刻: 2009/2/23 9:0
終了時刻: 2009/2/23 9:10
現時刻は指定期間「内」

追記: SimpleDateFormatによる出力の整形

d_kamiさんに改良していただきました。ありがとうございます(^-^)

String showTime(Calendar cal) {
Date date = cal.getTime();
SimpleDateFormat format = new SimpleDateFormat(“yyyy/MM/dd HH:mm”);
return format.format(date);
}
と書けばすっきりするよ、import java.text.SimpleDateFormatを忘れずに – SimpleDateFormat – マイペースなプログラミング日記

showTimeを修正して計りなおした実行結果は、

開始時刻: 2009/02/23 21:00
終了時刻: 2009/02/24 21:10
現時刻は指定期間「内」

確かに出力はyyyy/MM/dd HH:mmの形式になっていて見栄えも良いです。

参考サイト

Posted in Java | Tagged , , , | 1 Comment

Java, Swing: JComponentのGraphicsオブジェクトを用いて直線を描画

JComponentはほとんど全てのSwing コンポーネントの基底クラスで、Graphicsオブジェクトも持っています。下記のソースは、そのGraphicsを用いて画面に直線を描画するものです。

ソースコード

package linecomp;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Insets;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class LineComp extends JComponent {

  public static void main(String[] args) {
    Runnable myGUI = new Runnable() {
      @Override
      public void run() {
        JFrame win = new JFrame("Line Component");
        win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Insets ins = win.getInsets();
        win.setSize(300 + ins.left + ins.right, 300 + ins.top + ins.bottom);
        win.add(new LineComp());
        win.setVisible(true);
      }
    };
    SwingUtilities.invokeLater(myGUI); // 保留中のすべての AWT イベントが処理されたあとに発生
  }

  @Override
  public void paintComponent(Graphics g) {
    g.setColor(getBackground());
    g.fillRect(0, 0, getWidth(), getHeight());
    g.setColor(Color.RED);
    g.drawLine(0, 0, getWidth(), getHeight());
  }
}

GUI部品の(再)描画レンダリングが発生した際、オーバーライドしたpaintComponent()内の手続きをEventQueueに登録しEDT(Event Dispatch Thread)が処理をします。標準のGUI部品をカスタマイズしたい場合などに使えます。その場合は予めsuper.paintComponent(g);でデフォルトのレンダリングを基底クラスに任せ、その後にカスタムの描画処理を書きます。

実行結果

JComponent に線を描画

追記: d_kami さんに改良して頂きました

InsetとJFrame#setSizeを使わずにJComponent#setPreferredSizeとJFrame#packを使うようにした – 他のやり方 – マイペースなプログラミング日記

comp.setPreferredSize(new Dimension(300, 300));
win.add(comp);
win.pack();

確かにsetPreferredSizeでコンポーネントのサイズを直接指定したほうが今プログラムの文脈に沿っています。私のほうはコンポーネントでなくJFrameのサイズの指定ですから。また、オーバーライドしたpaintComponent()でgetWidth()やgetHeight()を二度使うのであれば、一度ローカル変数に格納することでオーバヘッドを下げるのも大切ですね。日頃からの習慣にしないと。
とても勉強になりました。ありがとうございます。

参考サイト

Posted in Java | Tagged , , | 1 Comment