• 検索結果がありません。

Factory Method 2003/07/18 特徴スーパークラスで複数のインスタンスを管理するためのパターン ( スーパークラス ( の型として ) で扱いたいインスタンスが存在するが, スーパークラスではそのインスタンスを生成せずにインターフェースだけを規定し, 各サブクラスでそのインスタン

N/A
N/A
Protected

Academic year: 2021

シェア "Factory Method 2003/07/18 特徴スーパークラスで複数のインスタンスを管理するためのパターン ( スーパークラス ( の型として ) で扱いたいインスタンスが存在するが, スーパークラスではそのインスタンスを生成せずにインターフェースだけを規定し, 各サブクラスでそのインスタン"

Copied!
12
0
0

読み込み中.... (全文を見る)

全文

(1)

−17−

Factory Method

特徴

スーパークラスで複数のインスタンスを管理するためのパターン

(スーパークラス(の型として)で扱いたいインスタンスが存在するが,スーパークラスではそのインスタン

スを生成せずにインターフェースだけを規定し,各サブクラスでそのインスタンスを生成させる.そして,

そのリストをインスタンスを作成したクラス(インスタンス)で保持する.) Template Method の応用事例

クラス図

Creator

create factoryMethod

ConcreteCreator

factoryMethod

Product

method1 method2 method3

ConcreteProduct

method1 method2 method3 Creates Creates

各クラスの説明

Product 製品:製品:製品:製品: (製品の)フレームワーク このパターンによって生成されるインスタンス(ConcreteProduct のインスタンス)が 持つべきインターフェースを定める抽象クラス ConcreteProduct 具体的製品具体的製品具体的製品具体的製品::::具体的な製品を定めるクラス. Creator 生産者:生産者:生産者:生産者:(生産者の)フレームワーク あるいは“工場”に対応 Product インスタンスを生成する抽象クラス 具体的な内容はサブクラスのConcreteCreator で設定する (Creator は Product を生成することしか役目を知らない) ConcreteCreator 具体的生産者具体的生産者具体的生産者具体的生産者::::具体的な製品を作るクラス

適用例

(「Java 言語で学ぶデザインパターン入門」より)

身分証明書カード(ID カード)を作る工場

(個人のカード(IDCard)を作成し,ID…Factory 内でリストに持つ) 各クラスの説明 Product 抽象メソッドuse のみ宣言されている抽象クラス Factory メソッドcreate を実装している抽象クラス IDCard メソッドuse を実装しているクラス

IDCardFactory メソッドcreateProduct, registerProduct を実装しているクラス

Main 動作テスト用クラス Factory create( ) createProduct( ) registerProduct( ) IDCardFactory owners( ) createProduct( ) registerProduct( ) getOwners( ) Product use( ) IDCard owner use( ) getOwner( ) Creates Creates 製品 工場

インターフェース

インスタンス生成

対象のクラス

これらは親クラスであり (各型の)変数 (各型の)変数 (各型の)変数 (各型の)変数を設定し, 利用する IDCard のインスタンスを作成する ICCard のインスタンスをリストに追加する IDCard のリスト(Vector クラス)の先頭アド レスを渡す(返す) リストに追加 (個々のカードの) インスタンスを作成 こちらの クラスが インスタンス 作成の対象 IDCard IDCard IDCard IDCard … IDCardFactory インスタンス IDCard インスタンス リスト

(2)

−18− プログラム

Product.java

public abstract class Product { public abstract void use(); }

IDCard.java

public class IDCard extends Product { private String owner;

IDCard(String owner) {

System.out.println(owner + "のカードを作ります。"); this.owner = owner;

}

public void use( ) {

System.out.println(owner + "のカードを使います。"); }

public String getOwner() { return owner;

} } Factory.java (((( 抽象クラス抽象クラス抽象クラス抽象クラス ))))

public abstract class Factory {

public final Product create(String owner) { Product p = createProduct(owner); registerProduct(p);

return p; }

protected abstract Product createProduct(String owner); protected abstract void registerProduct(Product product); }

IDCardFactory.java import java.util.*;

public class IDCardFactory extends Factory { private Vector owners = new Vector();

protected Product createProduct(String owner) { return new IDCard(owner);

}

protected void registerProduct(Product product) { owners.add(((IDCard)product).getOwner()); }

public Vector getOwners() { return owners;

} }

Main.java ( Main メソッド(( メソッドメソッドメソッド )))) public class Main {

public static void main(String[] args) { Factory factory = new IDCardFactory(); Product card1 = factory.create("山田太郎"); Product card2 = factory.create("関大太郎"); Product card3 = factory.create("関大花子"); card1.use(); card2.use(); card3.use(); } } 実行結果 ¥>java Main 山田太郎のカードを作ります。 関大太郎のカードを作ります。 関大花子のカードを作ります。 山田太郎のカードを使います。 関大太郎のカードを使います。 関大花子のカードを使います。

抽象クラス

メソッドも抽象

Product の継承 コンストラクタ 抽象メソッドの実装 抽象メソッド 実装されたメソッド 抽象メソッドを利用して実装 抽象メソッドの実装 Factory メソッドの継承 Factory (親クラス)の変数に IDCardFactory インスタンスを作成し,代入(インスタンスは1つ) 工場(factory)のメソッドを利用し て,各人のカード(製品)を作成 à 製品で受ける 製品を作成している(Product のインスタンス を作成)戻り値は‘製品’(そのインスタンス) 各人のカード(製品)の利用 (Owner の)リストを持つために Vector クラスのインスタンスを作成 リストに追加 IDCard クラスの getOwner( )に注意

(3)

−19−

Adapter

特徴

「既に存在するもの」と「必要なもの」を繋ぐためのパターン

「既に存在するもの」を「必要なもの」の形状に変換させて“ずれを”なくすパターン

既存のクラスを変更せず,目的のインターフェースに合わせるパターン

※2種類の実装方法が存在(継承を利用したもの,委譲を利用したもの).Wrapper パターンとも呼ばれる.

クラス図

Client <<interface>> Target targetMethod1( ) targetMethod2( ) Adapter targetMethod1( ) targetMethod2( ) Adaptee methodA( ) methodB( ) methodC( ) Uses implements extends 「継承」の利用によるAdapter パターン Client Adapter targetMethod1( ) targetMethod2( ) Adaptee methodA( ) methodB( ) methodC( ) Uses extends has 「委譲」の利用によるAdapter パターン Target targetMethod1( ) targetMethod2( )

各クラスの説明

Adaptee 適合される側:(適合される側:(適合される側:(適合される側:(Targetのメソッドとは異なる)用意されたメソッドを持つ(問題とされ る既存のクラス(システム)) Adapter 変換接合部分(アダプター):変換接合部分(アダプター):変換接合部分(アダプター):変換接合部分(アダプター):Adapteeのメソッドを利用してTargetのメソッドに対応 させるクラス(下の2パターンがある) ・「継承」を利用してAdapteeのメソッドを利用(Adapter のクラスで実装) ・「委譲」を利用してAdapteeのメソッドを利用(Adapter のインスタンスによって実 装) Target 対象:必要とするメソッドを決めているクラス(使用するメソッドを用意(宣言)する) Client 依頼者:Target のメソッド利用して仕事をするクラス

※ 委譲:「別のもの(人)に任せること」であり、Javaの場合では“あるインスタンスのメソッドの処理を別のイ

ンスタンスのメソッドに任せること”である.具体的にはあるインスタンスAの属性に別クラスのインスタンス

Bを持たせ,Aのメソッドの処理をBのメソッドによって実行する.

(4)

−20−

A

b

b

b

b

(B(B(B(B のオブジェクトのオブジェクトのオブジェクトのオブジェクト))))

func( ){

b.func( ) }

B

func( )

A のオブジェクトのメソッド func( )の処理が, B のオブジェクト b のメソッド func( )に任せられる

適用例

(「Java 言語で学ぶデザインパターン入門」より) 与えられた文字列に対して, ( 文字列 ) や *文字列* と,表示するメソッドを持つ既存のクラス(Banner)が存在する. 今,文字列を強くあるいは弱く表現するために上の ‘(‘ と ‘*’ をそれぞれ利用して表現したいが,文字列を強 くあるいは弱く表現するメソッド(クラス)も予め用意されているとする. このため,文字列を強くあるいは弱く表現するメソッドを変換させて,文字列を ’(’ あるいは ’*’ で表現する.

各クラスの説明

Print 今必要とするもの(必要とする処理を持つクラス) メソッド printWeak(文字列を弱く印刷),printStrong(文字列を強く印刷) PrintBanner 変換および適合部 Banner 予め与えられているもの(既存のもの,既存のメソッドが用意されているもの) メソッド showWithParen (括弧を付けて表示),showWithAster(*を付けて表示) Main 動作テスト用のMain クラス

継承によるパターン

Main <<interface>> Print printWeak( ) printStrong( ) PrintBanner printWeak( ) printStrong( ) Banner showWithParen( ) showWithAster( ) Uses implements extends 「継承」の利用によるAdapter パターン PrintBanner.java ( 変換および適合部変換および適合部:既存のクラス変換および適合部変換および適合部:既存のクラス:既存のクラス:既存のクラス の継承,必要とする機能のインターフェースには実装 の継承,必要とする機能のインターフェースには実装 の継承,必要とする機能のインターフェースには実装 の継承,必要とする機能のインターフェースには実装) public class PrintBanner extends Banner implements Print { public PrintBanner(String string) {

super(string); // 親クラスのコンストラクタ }

public void printWeak( ) { showWithParen( ); }

public void printStrong( ) { showWithAster( ); } } Banner.java(既存のクラス:このメソッドを利用す(既存のクラス:このメソッドを利用す(既存のクラス:このメソッドを利用す(既存のクラス:このメソッドを利用す る) る)る) る)

public class Banner { private String string;

public Banner(String string) { this.string = string; }

public void showWithParen() {

System.out.println("(" + string + ")"); }

public void showWithAster() {

System.out.println("*" + string + "*"); } } インターフェース のメソッド名を利 用して,親クラス ( 既 存 ク ラ ス Banner )のメソ ッドを呼ぶ 継承しているので自分のメソッドとなってい るので,メソッドのみの記述で呼び出せる

(5)

−21− Print.java ( インターフェースインターフェースインターフェースインターフェース )

public interface Print {

public abstract void printWeak(); public abstract void printStrong(); }

Main.java

public class Main {

public static void main(String[] args) { Print p = new PrintBanner("Hello"); p.printWeak(); p.printStrong(); } }

委譲によるパターン

Main PrintBanner banner printWeak( ) printStrong( ) Uses extends has 「委譲」の利用によるAdapter パターン Print printWeak( ) printStrong( ) Banner showWithParen( ) showWithAster( ) Print.java (((( 抽象抽象抽象(abstract) クラス抽象 クラスクラスクラス )))) public abstract class Print {

public abstract void printWeak(); public abstract void printStrong(); }

その他のクラス(Main, Banner )は同じ

PrintBanner.java ((((Print クラスからの継承(サブクラス))クラスからの継承(サブクラス))クラスからの継承(サブクラス))クラスからの継承(サブクラス)) public class PrintBanner extends Print {

private Banner banner;

public PrintBanner(String string) { this.banner = new Banner(string); }

public void printWeak() { banner.showWithParen(); }

public void printStrong() { banner.showWithAster(); } }

実行結果

¥>java Main

(Hello)

*Hello*

抽象メソッドの指定 実装はPrintBanner で行う 利用対象は必要とされる機能 (クラス)のメソッドを持つ PrintBanner メソッドも抽象

既存のクラスのイ

ンスタンスを持つ

コンストラクタで自 分のインス タン ス の 作 成 と 同 時 に Banner のインス タンスを作成する 抽象クラスのメソッドの実装で既存の クラス(Banner)のメソッドを呼ぶ

<委譲の利用>

(6)

−22−

Observer

特徴

観察対象の状態が変化すると,観察者に対して何らかの通知を行うパターン

状態の変化に応じた処理を記述するときに有効

クラス図

Subject observers addObserver deleteObserver nitifyObservers getSubjectStatus Observer update ConcreteObserver update ConcreteSubject getSubjectStatus Notifies

各クラスの説明

Subject

被験者「観察される側」(むしろ,状態の変化を通知する側)

観察者(Observer)を登録する(登録および削除するメソッドを持つ)

状態が変化したことを観察者に通知する

ConcreteSubject

具体的な被験者を設定するクラス

Observer

観察者「観察する側」 (通知を受けて変更を行なう側)

被験者(Subject)から状態の変化を教えてもらう(そして,具体的な観察者(子ク

ラス)に処理内容を指示する)

Concrete Observer

具体的な観察者を設定するクラス

(変更内容を教えてもらい(通知を受けて)変更をする)

適用例1

(「UMLPress Vol.1」より)

証券会社の新人社員 A さんの仕事は,日経平均の動向を調べ,前日の終値の±200 円を越えた場合

に顧客リストをもとに,各顧客に株価一覧を FAX することである.顧客には会社員,法人企業,学生などが

いる.なお,顧客リストの作成,メンテナンスは A さんの先輩が行う.

新人の仕事 −顧客リスト +顧客を追加する( ) +顧客を削除する( ) +顧客へ通知する( ) +株価一覧を取得する( ) +価格を調べる( ) <<interface>> FAX +FAX する( ) 個人 法人 学生 その他 A 君の仕事 +価格(平均株価)を調べる( ) 先輩 Observerパターンパターンパターンパターン 通知する

適用例2

(「Java 言語で学ぶデザインパターン入門」より)

数を多数発生させるオブジェクトを観察者(ConcreteSubject)が観察して,その値を表示する.

表示方法は観察者によって異なり,DigitObserver では値を数字で,GraphObserver ではグラフで表

示する.

(7)

−23− NumberGenerator observers addObserver( ) deleteObserver( ) nitifyObservers( ) getNumber( ) execute( ) <<interface>> Observer update DigitObserver update RandomNumberGenerator random number getNumber( ) execute( ) Notifies GraphObserver update

NumberGenerator.java (Subject に相当.数を生成し,その値を渡すクラス(抽象クラス)

に相当.数を生成し,その値を渡すクラス(抽象クラス)

に相当.数を生成し,その値を渡すクラス(抽象クラス)

に相当.数を生成し,その値を渡すクラス(抽象クラス))

import java.util.Vector; import java.util.Iterator;

public abstract class NumberGenerator {

private Vector observers = new Vector( ); // Observer たちを保持するためのリストの設定 public void addObserver(Observer observer) { // Observer を追加

observers.add(observer); }

public void deleteObserver(Observer observer) { // Observer を削除 observers.remove(observer);

}

public void notifyObservers() { // Observer へ通知 Iterator it = observers.iterator( ); while (it.hasNext()) { Observer o = (Observer)it.next( ); o.update(this); } }

public abstract int getNumber(); // 数を取得する public abstract void execute(); // 数を生成する }

RandomNumberGenerator.java (NumberGenerator クラスの実装部.

クラスの実装部.

クラスの実装部.

クラスの実装部.Subject の具象クラス

の具象クラス

の具象クラス)

の具象クラス

import java.util.Random;

public class RandomNumberGenerator extends NumberGenerator { private Random random = new Random(); // 乱数発生器 private int number; // 現在の数 public int getNumber() { // 数を取得する return number;

}

public void execute() {

for (int i = 0; i < 20; i++) {

number = random.nextInt(50); notifyObservers(); } } }

この2つのメソッドは

抽象メソッド

NumberGenerator は 抽象クラス NumberGenerator クラスで宣 言された2つの抽象メソッドはこ こで実装 Vector のオブジェ クトを作 成 し,この中に Observer のオブ ジェクトを格納する 親クラス(抽象クラス)内のメソッドを呼ぶ ここで画面表示 Vector 内に格納されて いる Observer のオブジ ェクトを1つずつ取り出す これはインターフェース なのでメソッドの宣言の み.実装は子クラスで行 なう. 実装するメソッド Obsever インスタ ン ス の リ ス ト へ の 追加 Obsever インスタ ンスのリストからの 削除 Obsever インスタ ンスへの状態変化 の通知

具体的に数(乱数)を生成し,その値を渡すクラス

親の型の変数 (DigiObserver, GraphObserver のインスタンスどちらでも入れられる) これが 重要

(8)

−24−

Observer.java (観察者のインターフェース

観察者のインターフェース

観察者のインターフェース

観察者のインターフェース)

public interface Observer {

public abstract void update(NumberGenerator generator); }

DigitObserver.java (Observer インターフェースの具象クラス

インターフェースの具象クラス

インターフェースの具象クラス)

インターフェースの具象クラス

public class DigitObserver implements Observer { public void update(NumberGenerator generator) {

System.out.println("DigitObserver:" + generator.getNumber()); try { Thread.sleep(100); } catch (InterruptedException e) { } } }

GraphObserver.java (Observer インターフェースの具象クラス

インターフェースの具象クラス

インターフェースの具象クラス)

インターフェースの具象クラス

public class GraphObserver implements Observer { public void update(NumberGenerator generator) { System.out.print("GraphObserver:");

int count = generator.getNumber(); for (int i = 0; i < count; i++) { System.out.print("*"); } System.out.println(""); try { Thread.sleep(100); } catch (InterruptedException e) { } } }

Main.java (処理実行用プログラム

処理実行用プログラム

処理実行用プログラム

処理実行用プログラム)

public class Main {

public static void main(String[] args) {

NumberGenerator generator = new RandomNumberGenerator(); Observer observer1 = new DigitObserver();

Observer observer2 = new GraphObserver(); generator.addObserver(observer1); // generator.addObserver(observer2); // generator.execute(); // 実行 } }

実行結果

updata のみの抽象メソッドとし て宣言(NumberGenerator の オブジェクトを引数 ) updata を実装 NumberGenerator のオブジェクト から数値を取り出し,数値を表示 updata を実装 NumberGenerator のオブジ ェクトから数値を取り出し,表と して表示(*の数で表示) ¥>java Main DigitObserver:47 GraphObserver:*********************************************** DigitObserver:48 GraphObserver:************************************************ DigitObserver:19 …… 2種類の観察者のオブジェクトをそ れぞれ作成型が Observer(抽象ク ラス) であることに注意 数値発生クラス(Subject) のオブジェクト作成 数値発生オブジェクトに観察者(処理する) オブジェクトをリストに登録する (これで NumberGenerator のインスタンス 変数 Observers のリスト内に DigitObserver のインスタンスが格納された) Generator(親の型)の変数を引数としている ので,子クラスのRandom… も利用できる

(9)

−25−

Facade

特徴

・複雑で多数存在する処理(のためのクラス)をまとめて,共通のインターフェースを提供するパターン

・システムの外部に対しては単純なインターフェースを見せ,システム内部の各クラスの役割や依存関

係から正しい順番でクラスを利用する(複雑な内部構造を外部に対しては単純に見せる)

・Facade パターンはシステムの外部に対する窓口

窓口

窓口

窓口に相当する

(Facade の語源は façade(「建物の正面」の意味))

クラス図

Client Facade ClassA ClassD ClassB ClassC Uses

各クラスの説明

Client

依頼人

Facade

依頼人「Client」に対する窓口

ClassA~D など

各処理

適用例

(UMLPress Vol.1 より)

洗濯機の代表的な機能には「洗う」,「すすぐ」,「脱水する」の 3 つである.ここで,「洗う」機能には「30

分かけて洗う」,「強めに洗う」、「丁寧に洗う」などの多種の洗い方が存在することが考えられ,さらに,「す

すぐ」や「脱水する」においても時間や処理法方法に細かに指定する必要がある.

しかし,これらを細かく設定する場合だけではなく,「お任せ洗い」のようにボタン一つにより処理を行う場

合もあり,全ての処理を自動処理する場合や細かく処理を指定して利用できることが必要である.

「お任せ洗い」のようにボタン一つで自動的に処理を行うシステム構成を Façade パターンによって実現

できる.

お任せ洗いボタン 洗濯する( ) 洗濯 洗い方を指定する( ) 時間を指定する( ) すすぎ すすぎ方を指定する( ) 時間を指定する( ) 脱水 脱水の仕方を指定する( ) 時間を指定する( ) 利用者

(10)

−26−

適用例2

(「Java 言語で学ぶデザインパターン入門」より) ユーザーのWeb ページを作成するシステムを実装する.システムは3つのクラスから構成される. これらは,メールアドレスから名前を得るデータベース(DataBase),HTML ファイルを作成するクラス (HtmlWriter),Facade 役のインターフェース(API)を提供するクラス(PageMaker)で構成される. [ [ [ [ 処理内容処理内容処理内容処理内容 ] ] ] ] 一つのメソッドで,引数にメールアドレスと html ファイルの名前のみを設定すれば, 自動的にメールアドレスを載せたホームページを作成し,データベース(mail.txt)にアドレスを登録で きるプログラムを考える.下記プログラムは PageMaker クラスのメソッド makeWelcomePage()を用 意し,関大花子さん (hanako@kandai.com)のホームページ(welcome.html)を作成する例である. PageMaker makeWelcomPage( ) HtmlWriter writer title( ) paragraph( ) link( ) mailto( ) close( ) Database getProperties( ) Main Uses Uses Uses

PageMaker

PageMaker

PageMaker

PageMaker.java (

.java (

.java (

.java (Façade

Façade

Façade

Façade 役のクラス:メールアドレスからユーザの

役のクラス:メールアドレスからユーザの

役のクラス:メールアドレスからユーザの

役のクラス:メールアドレスからユーザの

Web

Web ページを作成するクラス

Web

Web

ページを作成するクラス

ページを作成するクラス

ページを作成するクラス))))

package pagemaker;

import java.io.FileWriter; import java.io.IOException; import java.util.Properties; public class PageMaker {

private PageMaker() { // インスタンスは作らないので private 宣言する }

public static void makeWelcomePage(String mailaddr, String filename) { try {

Properties mailprop = Database.getProperties("maildata"); //Database のクラスメソッド String username = mailprop.getProperty(mailaddr);

HtmlWriter writer = new HtmlWriter(new FileWriter(filename)); // HtmlWriter の // コンストラクタ writer.title("Welcome to " + username + "'s page!"); // HtmlWriter のメソッド writer.paragraph(username + "のページへようこそ。"); // HtmlWriter のメソッド writer.paragraph("メールまっていますね。"); // HtmlWriter のメソッド writer.mailto(mailaddr, username); // HtmlWriter のメソッド writer.close(); // HtmlWriter のメソッド System.out.println(filename + " is created for " + mailaddr + " (" + username + ")");

} catch (IOException e) { e.printStackTrace(); } } } HtmlWriter.java (個々の処理:個々の処理:個々の処理:個々の処理:HTML ファイルを作成するクラスファイルを作成するクラスファイルを作成するクラス)ファイルを作成するクラス package pagemaker; HtmlWriter クラス と Database クラス からなる処理が記述

まとめられた一連の処理

関連するクラスのオブジェ クトを作成(そのクラスのメ ソッドを実行するため) データベース(ファイルの)名前

(11)

−27− import java.io.Writer;

import java.io.IOException; public class HtmlWriter { private Writer writer;

public HtmlWriter(Writer writer) { // コンストラクタ this.writer = writer;

}

public void title(String title) throws IOException { // タイトルの出力 writer.write("<html>");

writer.write("<head>");

writer.write("<title>" + title + "</title>"); writer.write("</head>");

writer.write("<body>¥n");

writer.write("<h1>" + title + "</h1>¥n"); }

public void paragraph(String msg) throws IOException { // 段落の出力 writer.write("<p>" + msg + "</p>¥n");

}

public void link(String href, String caption) throws IOException { // リンクの出力 paragraph("<a href=¥"" + href + "¥">" + caption + "</a>");

}

public void mailto(String mailaddr, String username) throws IOException { // メールアドレスの出力 link("mailto:" + mailaddr, username);

}

public void close() throws IOException { // 閉じる writer.write("</body>"); writer.write("</html>¥n"); writer.close(); } } Database Database Database

Database.java (.java (.java (.java (個々の処理個々の処理個々の処理個々の処理:メールアドレスからユーザを得るクラス:メールアドレスからユーザを得るクラス:メールアドレスからユーザを得るクラス:メールアドレスからユーザを得るクラス) package pagemaker;

import java.io.FileInputStream; import java.io.IOException; import java.util.Properties; public class Database {

private Database() { // new でインスタンス生成させないために private 宣言 }

public static Properties getProperties(String dbname) { // データベース名から Properties を得る String filename = dbname + ".txt";

Properties prop = new Properties(); try {

prop.load(new FileInputStream(filename)); } catch (IOException e) {

System.out.println("Warning: " + filename + " is not found."); } return prop; } } main.java (動作動作動作テスト用の実行部のクラス動作テスト用の実行部のクラステスト用の実行部のクラステスト用の実行部のクラス) import pagemaker.PageMaker;

public class Main {

public static void main(String[] args) {

PageMaker.makeWelcomePage("hanako@kandai.com", "welcome.html"); } } Pagemaker フ ォ ル ダ 内 の PageMaker.java を import PageMaker のクラスメソッド makeWelcomePage() を実行 (引数はアドレスと出力ファイル名) HTML ファイルの タグを書く部分 メッセージの出力 リンク先の出力 メールアドレスの 出力 プロパティを作成し,読 み込んだデータを返す データベース名(ファイル名)

(12)

−28−

パッケージ ファイル名(クラス名) 特徴

pagemaker Database メールアドレスからユーザ名を得るクラス

データベース名を指定してProperties を作成するクラス pagemaker HtmlWriter HTML ファイルを作成するクラス

pagemaker PageMaker メールアドレスからユーザのWeb ページを作成するクラス

Main 動作テストのクラス

実行結果

¥>java Main

welcome.html is created for hanako@kandai.com (Kandai Hanako) maildata.txt の中身 taro@yamada.com=Yamada Taro taro@kandai.com=Kandai Taro hanako@kandai.com=Kandai Hanako ――― Main.java <<ディレクトリ構造>> ―― mail.txt ←メールのデータベース←メールのデータベース←メールのデータベース←メールのデータベース ―― welcome.html ←実行時に作成 ―― pagemaker ―― Database.java ―― HtmlWriter.java ―― PageMaker.java Welcome.html 内の記述

<html><head><title>Welcome to Kandai Hanako's page!</title></head><body> <h1>Welcome to Kandai Hanako's page!</h1>

<p>Kandai Hanako のページへようこそ。</p> <p>メールまっていますね。</p>

<p><a href="mailto:hanako@kandai.com">Kandai Hanako</a></p> </body></html>

参照

関連したドキュメント

が前スライドの (i)-(iii) を満たすとする.このとき,以下の3つの公理を 満たす整数を に対する degree ( 次数 ) といい, と書く..

(2)特定死因を除去した場合の平均余命の延び

えて リア 会を設 したのです そして、 リア で 会を開 して、そこに 者を 込 ような仕 けをしました そして 会を必 開 して、オブザーバーにも必 の けをし ます

AMS (代替管理システム): AMS を搭載した船舶は規則に適合しているため延長は 認められない。 AMS は船舶の適合期日から 5 年間使用することができる。

本手順書は複数拠点をアグレッシブモードの IPsec-VPN を用いて FortiGate を VPN

しかし , 特性関数 を使った証明には複素解析や Fourier 解析の知識が多少必要となってくるため , ここではより初等的な道 具のみで証明を実行できる Stein の方法

・性能評価試験における生活排水の流入パターンでのピーク流入は 250L が 59L/min (お風呂の

「海洋の管理」を主たる目的として、海洋に関する人間の活動を律する原則へ転換したと