2010/06/22

デザインパターンの復習(Singleton)

ずっと前に勉強したデザインパターン。
仕事で使わないため、忘れないようメモメモ。

Singletonとは
GoFによるデザインパターンの一種Singletonパターンのことで、あるクラスのインスタンスを一つしか生成しないよう保証するための方法です。
(僕の中では)一番簡単なデザインパターンです。
それにしても、GoFってGang of Fourの略らしい・・・中二病なのかな。

Singletonの利点
プログラム中でインスタンスが必ず一つとなることが保証されていることです。
このおかげで、不必要なインスタンス生成を防ぐことができ、予期しないバグの発生防止や余計なメモリ使用防止に役立ちます。
Singletonを実装するクラスの”唯一のインスタンス”は、クラス初期化時にnewされます。



※なお、下のソースコードは、突っ込みどころ満載かもしれません。
・気付いた人は優しく教えてあげてください。
・例外は、現在の環境では使用可能でない場合にスローだったりするので、今回は何もしない。
・鍵の申請書は面倒なので今回はしない。



Singletonパターンを使ったクラス

package shinya.crypto;

import java.security.InvalidKeyException;
import javax.crypto.IllegalBlockSizeException;
import java.security.NoSuchAlgorithmException;
import java.io.UnsupportedEncodingException;
import javax.crypto.BadPaddingException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.Cipher;

/**
* 共通鍵暗号のBlowfishアルゴリズムで暗号/復号を行うクラス
*/
public class Blowfish {

/** 唯一のインスタンス */
private static final Blowfish blowfish = new Blowfish();

/** 暗号化アルゴリズム */
private static final String BLOWFISH = "Blowfish";

/**
* Constractor
*/
private Blowfish() {}

/**
* インスタンスを取得する
* @return 唯一のインスタンス
*/
public static Blowfish getInstance() {
return blowfish;
}

/**
* Blowfishで暗号文を生成する
* @param key 秘密鍵
* @param plainText 平文
*/
public byte[] encrypt(String key, String plainText) throws IllegalBlockSizeException, InvalidKeyException,
NoSuchAlgorithmException, UnsupportedEncodingException,
BadPaddingException, NoSuchPaddingException {
// Blowfish用秘密鍵を生成。
SecretKeySpec sksSpec = new SecretKeySpec(key.getBytes(), BLOWFISH);

// 暗号文を生成。
Cipher cipher = Cipher.getInstance(BLOWFISH);
cipher.init(Cipher.ENCRYPT_MODE, sksSpec);
byte[] encryptedText = cipher.doFinal(plainText.getBytes());

return encryptedText;
}

/**
* Blowfishで複合する
* @param key 秘密鍵
* @param encrypted 暗号文
*/
public String decrypt(String key, byte[] encryptedText) throws IllegalBlockSizeException, InvalidKeyException,
NoSuchAlgorithmException, UnsupportedEncodingException,
BadPaddingException, NoSuchPaddingException {
// Blowfish用秘密鍵を生成。
SecretKeySpec sksSpec = new SecretKeySpec(key.getBytes(), BLOWFISH);

// 暗号文を復号する。
Cipher cipher = Cipher.getInstance(BLOWFISH);
cipher.init(Cipher.DECRYPT_MODE, sksSpec);
byte[] decryptedText = cipher.doFinal(encryptedText);

return new String(decryptedText);
}
}





呼びだし側


import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

import shinya.crypto.Blowfish;

/**
* Main Class
*/
public class Main {

/**
* main method
* @throws NoSuchPaddingException
* @throws BadPaddingException
* @throws UnsupportedEncodingException
* @throws NoSuchAlgorithmException
* @throws IllegalBlockSizeException
* @throws InvalidKeyException
*/
public static void main(String[] args) throws InvalidKeyException, IllegalBlockSizeException,
NoSuchAlgorithmException, UnsupportedEncodingException,
BadPaddingException, NoSuchPaddingException {

String plainText = "ore ore";
byte[] encryptedText = Blowfish.getInstance().encrypt("key", plainText);
System.out.println("encrypt: " + encryptedText);


String decryptedText = Blowfish.getInstance().decrypt("key", encryptedText);
System.out.println("decrypt: " + decryptedText);
}
}