TOP比較データ> Singletonパターンによる比較

徹底比較!! PHP & Java

第3回:PHP4とJavaのオブジェクト指向

著者:ワイズノット  土橋 芳孝   2004/12/06
前のページ  1  2  3  次のページ
Singletonパターンによる比較

   先ほど、オブジェクト指向を利用したソフトウェア開発の利点を3点挙げましたが、この利点を享受するためにはオブジェクト指向に基づいた正しい設計が必要不可欠となります。このオブジェクト指向設計の教科書ともいえるものにデザインパターンがあります。デザインパターンとは、オブジェクト指向設計の定番いわば定石を集めたもので、オブジェクト指向設計のノウハウが分かりやすくまとめられています。

   今回は、GoF(the Gang of Four)のデザインパターンの中でも最も簡単なSingletonパターンを利用して、PHP4とJavaのオブジェクト指向を比較してみたいと思います。Singletonパターンは、オブジェクトを生成する個数を制限するために利用するもので、データベースのコネクションプールを開発する時などにも頻繁に利用されます。Singletonパターンでは、制限した個数を超えたオブジェクトを生成しようとした場合、既に生成済みのオブジェクトを再利用するための仕組みを提供します。
PHP4版  Singletonパターン
<?php
class Singleton {

// メッセージを格納する変数
var $msg = null;

// コンストラクタ
function Singleton() {
echo "オブジェクトを生成しました\n";
}

// オブジェクトを生成する
function &getInstance() {
static $singleton;
if ($singleton == null) {
$singleton = new Singleton();
} else {
echo "オブジェクトは既に存在します\n";
}
return $singleton;
}

// メッセージを格納する
function setMsg($str) {
$this->$msg = $str;
}
// メッセージを取得する
function getMsg() {
return $this->$msg;
}
}

echo "処理を開始しました\n";

// getInstance()でオブジェクトを生成する
$obj1 =& Singleton::getInstance();
$obj1->setMsg('$obj1 =& Singleton::getInstance()');
echo "obj1 : ".$obj1->getMsg()."\n";

// getInstance()でオブジェクトを生成する
$obj2 =& Singleton::getInstance();
$obj2->setMsg('$obj2 =& Singleton::getInstance()');
echo "obj1 : ".$obj1->getMsg()."\n";
echo "obj2 : ".$obj2->getMsg()."\n";

// 直接オブジェクトを生成する
$obj3 = new Singleton();
$obj3->setMsg('$obj3 = new Singleton()');
echo "obj1 : ".$obj1->getMsg()."\n";
echo "obj2 : ".$obj2->getMsg()."\n";
echo "obj3 : ".$obj3->getMsg()."\n";

echo "処理を終了しました\n";
?>

PHP4版  Singletonパターンの実行結果
処理を開始しました
オブジェクトを生成しました
obj1 : $obj1 =& Singleton::getInstance()
オブジェクトは既に存在します
obj1 : $obj2 =& Singleton::getInstance()
obj2 : $obj2 =& Singleton::getInstance()
オブジェクトを生成しました
obj1 : $obj2 =& Singleton::getInstance()
obj2 : $obj2 =& Singleton::getInstance()
obj3 : $obj3 = new Singleton()
処理を終了しました

   PHP4版Singletonパターンには問題があります。上記プログラムにおいて3回目にオブジェクトを生成する際、Singletonクラスを直接オブジェクト化していますが、それによって3回目のオブジェクト生成では、Singletonパターンでは許されない全く別のオブジェクトを生成しています。

   Singletonパターンは本来、開発者の意識やスキルに依存することなくオブジェクトを生成する個数を制限できなければなりません。つまりSingletonパターンではgetInstanceメソッドでしかオブジェクトを生成できない仕組みを実現しなければいけません。しかし、PHP4には変数や関数に対するアクセス制限の機能がないため、上記プログラムでは開発者がSingletonクラスを直接オブジェクト化することを防げません。

   一方、JavaでSingletonパターンを実現すると下記のとおりとなります。

Java版  Singletonパターン
class Singleton {

// シングルトンオブジェクトを格納する変数
private static Singleton singleton = null;

// メッセージを格納する変数
private String msg = null;

// コンストラクタ
private Singleton() {
System.out.println("オブジェクトを生成しました");
}

// オブジェクトを生成する
public static synchronized Singleton getInstance() {
if (singleton == null) {
singleton = new Singleton();
} else {
System.out.println("オブジェクトは既に存在します");
}
return singleton;
}

// メッセージを格納する
public void setMsg(String str) {
this.msg = str;
}
// メッセージを取得する
public String getMsg() {
return this.msg;
}
}


public class SingletonMain {
public static void main(String[] args) {
System.out.println("処理を開始しました");

// getInstance()でオブジェクトを生成する
Singleton obj1 = Singleton.getInstance();
obj1.setMsg("obj1 = Singleton.getInstance()");
System.out.println("obj1 : " + obj1.getMsg());

// getInstance()でオブジェクトを生成する
Singleton obj2 = Singleton.getInstance();
obj2.setMsg("obj2 = Singleton.getInstance()");
System.out.println("obj1 : " + obj1.getMsg());
System.out.println("obj2 : " + obj2.getMsg());

// 直接オブジェクトを生成する
Singleton obj3 = new Singleton();
obj3.setMsg("obj3 = new Singleton()");
System.out.println("obj1 : " + obj1.getMsg());
System.out.println("obj2 : " + obj2.getMsg());
System.out.println("obj3 : " + obj3.getMsg());
System.out.println("処理を終了しました");
}
}

Java版  Singletonパターンのコンパイル結果
SingletonMain.java:52: Singleton() は Singleton で
private アクセスされます。
Singleton obj3 = new Singleton();
^
エラー 1 個

   Java版Singletonパターンにおいても3回目のオブジェクト生成はSingletonクラスを直接オブジェクト化するようにコードを書きました。しかし、上記「Java版 Singletonパターンのコンパイル結果」をご覧のとおり、コンパイル時にエラーが発生します。PHP4と違いJavaには変数や関数に対するアクセス制限の機能があるため、SingletonパターンにおいてSingletonクラスを直接オブジェクト化することはできません。つまり、Singletonクラスをオブジェクト化する場合、開発者はgetInstanceメソッドの利用を強制されます。そのような仕組みによってSingletonパターンは開発者の意識やスキルに依存することなく、オブジェクトを生成する個数を制限することが可能となっています。

   以上のとおり、PHP4のオブジェクト指向はまだまだ発展途上といった観があります。変数や関数に対するアクセス制限の機能を持たないPHP4では、堅牢なアーキテクチャを実現することが困難だといえるでしょう。また、PHP4では抽象クラスや抽象メソッド、インターフェースといったオブジェクト指向にとって重要な機能を備えていません。そのため、Javaと比較してコードの拡張性や再利用性、保守性といったものが低下することは否めません。これら大規模企業システムにとって必須の要件を満たしていないPHP4では、大規模な企業システムを開発することが困難だと言えるのではないでしょうか。

前のページ  1  2  3  次のページ



著者プロフィール
株式会社ワイズノット  土橋 芳孝
以前はJavaを利用したWebアプリケーション開発とオブジェクト指向設計を得意としていたが、ワイズノットに入社以来、PHPの魅力にとりつかれる。現在はワイズノットのプロジェクトマネージャーとして、PHPをはじめとしたオープンソースの普及に力を注いでいる。


INDEX
第3回:PHP4とJavaのオブジェクト指向
  オブジェクト指向とは
Singletonパターンによる比較
  例外処理の比較