設計模式 - Prototype

Prototype 模式:

  • 當對象種類繁多的時候,我們可以把它們合併到一個類中去。
  • 難以根據類生成實例的時候。
  • 想解耦框架和生成的實例時,使生成框架不依賴於任何類。
  • 當一個實例進行了很多操作,比如關於字段的存入,一些方法對於類內字段的處理時,如果我們想要對實例進行復用,我們就可以考慮使用這種模式,我們不僅將實例複製了,省去了很多操作,而且實例之間雖然字段相同,但是已經是兩個實例,操作互不影響,也就是直接clone一個實例來用,爲了解耦不去幹擾已經用過這個實例的操作。

實例:

  • Sport 類表示運動的接口,需要繼承Cloneable 接口,以及Football,Basketball兩個類來表示足球和籃球,以及需要實現的方法時howToPlay,getBestPlayer。
  • 我們可以使用Manager類來返回複製後的Football,Basketball,比如Manager類中的setSport方法,我們會要求存儲關於這項運動男子的最佳運動員的名字,現在我們不太需要變更最佳運動員以及怎麼進行運動的信息,這個時候我們可以使用一次存入,多次clone。

Sport 接口:

package com.zyy.pattern.service;


public interface Sport extends Cloneable{
	public String howToPlay();
	public String getBestPlayer();
	public void showMessage();
	public Sport cloneSport();
}

Football 類:

package com.zyy.pattern.beans;

import static org.hamcrest.CoreMatchers.nullValue;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.zyy.pattern.service.Sport;

public class Football implements Sport{
	private Logger logger = LoggerFactory.getLogger(Football.class);
	private String bestPlayerName;
	public Football(String bestPlayerName) {
		this.bestPlayerName = bestPlayerName;
	}
	@Override
	public String howToPlay() {
		return "you can play with a ball by your foot";
	}

	@Override
	public String getBestPlayer() {
		return bestPlayerName;
	}

	@Override
	public void showMessage() {
		logger.info("how tot play : {} , the best player : {}",howToPlay(),getBestPlayer());
		
	}
	@Override
	public Sport cloneSport() {
		Sport sport = null;
		try {
			sport = (Sport) clone();
		} catch (CloneNotSupportedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return sport;
	}

}

Basketball 類:

package com.zyy.pattern.beans;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.zyy.pattern.service.Sport;

public class Basketball implements Sport{
	private Logger logger = LoggerFactory.getLogger(Basketball.class);
	private String bestPlayerName;
	public Basketball(String bestPlayerName) {
		this.bestPlayerName = bestPlayerName;
	}
	@Override
	public String howToPlay() {
		return "you can play with a ball by your hand";
	}

	@Override
	public String getBestPlayer() {
		return bestPlayerName;
	}

	@Override
	public void showMessage() {
		logger.info("how tot play : {} , the best player : {}",howToPlay(),getBestPlayer());
		
	}

	@Override
	public Sport cloneSport() {
		Sport sport = null;
		try {
			sport = (Sport) clone();
		} catch (CloneNotSupportedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return sport;
	}

}

Manager 類:

package com.zyy.pattern.beans;


import java.util.HashMap;

import com.zyy.pattern.service.Sport;

public class Manager {
	private HashMap<String, Sport> managerMap = new HashMap<>();
	public void register(String name,Sport sport) {
		managerMap.put(name, sport);
	}
	public Sport create(String name) {
		return managerMap.get(name).cloneSport();
	}
}

測試用例以及測試結果:

public void prototypePatternTest() {
		Basketball basketball = new Basketball("LeBron James");
		Football football = new Football("Lionel Messi");
		Manager manager = new Manager();
		manager.register("basketball", basketball);
		manager.register("football", football);
		Sport sportFirst = manager.create("basketball");
		Sport sportSecond = manager.create("basketball");
		Sport sportThird = manager.create("football");
		Sport sportForth = manager.create("football");
		sportFirst.showMessage();
		sportSecond.showMessage();
		sportThird.showMessage();
		sportForth.showMessage();
		logger.info("basketball == : {}",sportFirst == sportSecond);
		logger.info("football == : {}",sportThird == sportForth);
	}

21:20:42.915 [main] INFO com.zyy.pattern.beans.Basketball - how tot play : you can play with a ball by your hand , the best player : LeBron James
21:20:42.918 [main] INFO com.zyy.pattern.beans.Basketball - how tot play : you can play with a ball by your hand , the best player : LeBron James
21:20:42.918 [main] INFO com.zyy.pattern.beans.Football - how tot play : you can play with a ball by your foot , the best player : Lionel Messi
21:20:42.918 [main] INFO com.zyy.pattern.beans.Football - how tot play : you can play with a ball by your foot , the best player : Lionel Messi
21:20:42.918 [main] INFO testSpringFirst.DesignPatternTest - basketball == : false
21:20:42.918 [main] INFO testSpringFirst.DesignPatternTest - football == : false

Cloneable 接口:

  • 這是一個標記接口,它並沒有聲明任何方法,實現clone方法的是Object類,這個接口的存在只是判定能不能使用clone()這個方法。
  • clone()只是淺複製,只是複製了字段而已。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章