スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Singleton

Singletonパターン
唯一のインスタンスであることを保証する。

OnlyOne.java

public class OnlyOne {

private static OnlyOne onlyOne = new OnlyOne();
private OnlyOne(){}
public static OnlyOne getInstance(){
return onlyOne;
}
}
スポンサーサイト

Factory Methodパターン

Factory Methodパターン

インスタンス生成の工場。
構成としてはTemplate Methodパターンを利用している。
すなわち、スーパークラスで処理の枠組みを記述して、
具体的な肉付けはサブクラスで行う。

まず、抽象クラスで、工場とはcreateメソッドでSingerクラスのインスタンスを
生成するものと規定している。要するに処理の枠組みを決めている。
実際の実装はサブクラスに任せる。


package framework;

public abstract class Factory {
public final Singer create(String name){
Singer singer = createSinger(name);
registerSinger(singer);
return singer;
}
protected abstract Singer createSinger(String name);
protected abstract void registerSinger(Singer singer);
}


これも抽象クラス。

package framework;

public abstract class Singer {
public abstract void sing();
}


サブクラスでは、実際にcreateSingerを実装しています。

package jpop;

import java.util.ArrayList;
import java.util.List;

import framework.Factory;
import framework.Singer;

public class JpopSingerFactory extends Factory {

private List singers = new ArrayList();
@Override
protected Singer createSinger(String name) {
return new JpopSinger(name);
}

@Override
protected void registerSinger(Singer singer) {
singers.add((((JpopSinger)singer).getName()));
}
}





package jpop;

import framework.Singer;

public class JpopSinger extends Singer {

private String name;

public JpopSinger(String name) {
this.name = name;
}

@Override
public void sing() {
System.out.println(this.name + "です。歌います。");
}

public String getName() {
return name;
}

}


実行例はこんな感じ。

import jpop.JpopSingerFactory;
import framework.Factory;
import framework.Singer;

public class Main {
public static void main(String[] args){
Factory factory = new JpopSingerFactory();
Singer singer1 = factory.create("Ayaka");
Singer singer2 = factory.create("EXILE");
Singer singer3 = factory.create("大塚愛");

singer1.sing();
singer2.sing();
singer3.sing();
}
}


Factory Methodパターンを使用することで、以下のようなメリットがあると考えられる。
①サブクラスがおんなじインタフェースで統一できる。createSingerを呼べばよいんだな、と一目でわかる。
②拡張が簡単になる。たとえば、新たに演歌歌手を生成したい場合には、それぞれ対応するサブクラスを作って
やるだけでよい。サブクラスの修正、新規作成の影響がスーパークラスに及ぶことはない。

Template Methodパターン

Template Methodパターン
スーパークラスでは処理の枠組みを決めて、サブクラスで具体的な処理内容を実装する。
処理の大枠に差がないような場合に、TemplateMethodの使用価値が高くなる。

まず、スーパークラスにおおまかな処理の流れを定める(work()メソッドのアルゴリズムだけ決めておく)。
細かい具体的な処理内容は、後のサブクラスにお任せすることとする。

public abstract class AbstractProgrammer {
public abstract void goToTheOffice();//オフィスに来る(出社する)。
public abstract void programming();//プログラミングを行う。
public abstract void goHome();//帰宅する。

/** 8時間コーディングして、帰宅する。
*
*/
public final void work(){
goToTheOffice();
for(int hour=0;hour<8;hour++){
System.out.println(this.getClass().getName()+"の"+ hour + "時間め:");
programming();
}
goHome();
}
}


サブクラスに任せる部分の処理を記述していく。

public class JavaProgrammer extends AbstractProgrammer {

private String myLanguage = "Java";

@Override
public void goHome() {
// TODO 自動生成されたメソッド・スタブ
System.out.println("車で帰宅するぞ。");
}

@Override
public void goToTheOffice() {
// TODO 自動生成されたメソッド・スタブ
System.out.println("****今日も" + this.myLanguage + "でコーディングするぞ!****");
}

@Override
public void programming() {
// TODO 自動生成されたメソッド・スタブ
System.out.println("コンパイルしてます。Eclipse使ってます。");
}

}



public class PhpProgrammer extends AbstractProgrammer {

private String myLanguage = "PHP";

@Override
public void goHome() {
// TODO 自動生成されたメソッド・スタブ
System.out.println("徒歩で帰宅するぞ。");
}

@Override
public void goToTheOffice() {
// TODO 自動生成されたメソッド・スタブ
System.out.println("****今日も" + this.myLanguage + "でコーディングするぞ!****");
}

@Override
public void programming() {
// TODO 自動生成されたメソッド・スタブ
System.out.println("コンパイルとか不要です。Aptana Studio使ってます。");
}

}


最初にテンプレートを定めてロジックを共通化しておくことで、全員が正しくworkすることができる。
実行例はこんな感じ。

public class Main {
public static void main(String[] args){

AbstractProgrammer pg1 = new JavaProgrammer();
pg1.work();

AbstractProgrammer pg2 = new PhpProgrammer();
pg2.work();
}
}


実行例はこんな感じ。

****今日もJavaでコーディングするぞ!****
JavaProgrammerの0時間め:
コンパイルしてます。Eclipse使ってます。
JavaProgrammerの1時間め:
コンパイルしてます。Eclipse使ってます。
JavaProgrammerの2時間め:
コンパイルしてます。Eclipse使ってます。
JavaProgrammerの3時間め:
コンパイルしてます。Eclipse使ってます。
JavaProgrammerの4時間め:
コンパイルしてます。Eclipse使ってます。
JavaProgrammerの5時間め:
コンパイルしてます。Eclipse使ってます。
JavaProgrammerの6時間め:
コンパイルしてます。Eclipse使ってます。
JavaProgrammerの7時間め:
コンパイルしてます。Eclipse使ってます。
車で帰宅するぞ。
****今日もPHPでコーディングするぞ!****
PhpProgrammerの0時間め:
コンパイルとか不要です。Aptana Studio使ってます。
PhpProgrammerの1時間め:
コンパイルとか不要です。Aptana Studio使ってます。
PhpProgrammerの2時間め:
コンパイルとか不要です。Aptana Studio使ってます。
PhpProgrammerの3時間め:
コンパイルとか不要です。Aptana Studio使ってます。
PhpProgrammerの4時間め:
コンパイルとか不要です。Aptana Studio使ってます。
PhpProgrammerの5時間め:
コンパイルとか不要です。Aptana Studio使ってます。
PhpProgrammerの6時間め:
コンパイルとか不要です。Aptana Studio使ってます。
PhpProgrammerの7時間め:
コンパイルとか不要です。Aptana Studio使ってます。
徒歩で帰宅するぞ。

Adapterパターン

Adapterパターン
既にあるものがそのまま再利用できないときに、適切な形に変換してから利用する。
Adapterパターンには、継承を使ったパターンと委譲を使ったパターンとの2通りがある。
再利用したいクラスそのものには、いっさい変更を加えないところがポイント。

ビジネスアプリのプログラマに、BtoCのアプリケーションを作成して欲しいのだが、
そのままではうまくいかない(本人はBtoBのアプリケーションしか作成できないと考えている。)

public class BusinessApplicationProgrammer {
public void makeBtoBAppl(){
System.out.println("プログラムできました!");
}
}


そこで、一枚皮をかぶせて、このプログラマの能力を生かせるようにインターフェースを合わせる。
呼び出し側は、本当はBtoCのプログラムを作成してほしいので、まずは要求にあったインターフェースを作成する。

public interface BtoCApplicationProgrammer {
public void makeBtoCAppl();
}


用意したインターフェースを実装して、発想を転換した新しいPGを用意する。

public class NewProgrammer extends BusinessApplicationProgrammer implements BtoCApplicationProgrammer {
@Override
public void makeBtoCAppl() {
makeBtoBAppl();
}
}


これで、マネージャの要求(BtoCアプリ作成)に答えられるプログラマのできあがり。
BtoBアプリ作成の能力を、BtoCアプリ作成にも活かせるようになった。

public class Manager {
public static void main(String[] args){
NewProgrammer newPg = new NewProgrammer();
newPg.makeBtoCAppl();
}
}

Iteratorパターン

Iteratorパターン
中身を知らなくとも、順々にアクセスできる。

2つのインターフェースを用意する。

public interface Aggregate {
public abstract Iterator iterator();
}
public interface Iterator {
public abstract boolean hasNext();
public abstract Object next();
}


以下の通りにクラスを用意する。

public class Fruit {
private String name;
private int price;

public Fruit(String name, int price){
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
}
import java.util.ArrayList;

public class FruitList implements Aggregate{
private ArrayList fruits;
public FruitList(){
this.fruits = new ArrayList();
}
@Override
public Iterator iterator() {
// TODO 自動生成されたメソッド・スタブ
return new FruitListIterator(this);
}
public int getLength(){
return fruits.size();
}
public Fruit getFruitAt(int index){
return fruits.get(index);
}
public void addFruit(Fruit fruit){
this.fruits.add(fruit);
}

}
public class FruitListIterator implements Iterator{

private FruitList fruitlist;
private int index;

public FruitListIterator(FruitList fruitlist){
this.fruitlist = fruitlist;
this.index = 0;
}
@Override
public boolean hasNext() {
if(this.index < fruitlist.getLength()){
return true;
}else{
return false;
}
}

@Override
public Object next() {
Fruit fruit = fruitlist.getFruitAt(index);
index++;
return fruit;
}
}


これを実行する。

public class Main{
public static void main(String[] args){
FruitList fruitlist = new FruitList();

fruitlist.addFruit(new Fruit("apple",300));
fruitlist.addFruit(new Fruit("orange",200));
fruitlist.addFruit(new Fruit("strawberry", 400));

FruitListIterator itr = (FruitListIterator)fruitlist.iterator();
while(itr.hasNext()){
Fruit fruit = (Fruit)itr.next();
System.out.println(fruit.getName());
}
}
}

このMainクラスの繰り返し部分の中で、FruitList、FruitListIterator特有の処理を知る必要はないので、
再利用に適しているとされる。当然、hasnext(),next()の存在は知っている必要がある。
プロフィール

tjnet777

Author:tjnet777
Solaris, VPNのサポート業務を1年

金融系SIerで業務アプリの開発、メンテを3年半

離職して大学院大学 1年生

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QR
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。