設計模式(一) 觀察者模式、裝飾模式、工廠模式
阿新 • • 發佈:2019-01-08
---------------------- ASP.Net+Android+IOS開發、.Net培訓、期待與您交流! ----------------------
1.觀察者模式
觀察者模式: 定義了物件之間的一對多依賴,這樣一來,當一個物件改變狀態時,它的所有依賴者都會收到通知並自動更新。
首先我們需要一個 主題介面,物件可以使用該介面註冊為觀察者或者將自己從觀察者中刪除:
Subject介面:
/* * 主題介面,物件使用此介面註冊為觀察者或者將自己從觀察著中刪除 */ public interface Subject { /* * 註冊觀察者 */ public void registObserver(Observer observer); /* * 刪除觀察者 */ public void removeObserver(Observer observer); /* * 提醒觀察者更新資料 */ public void notifyObserver(); }
Observer介面:
public interface Observer {
/*
* 更新資料
*/
public void update(String team,String score);
}
Subject實現類MatchData:
public class MatchData implements Subject{ public void registObserver(Observer observer) { this.observers.add(observer); } public void removeObserver(Observer observer) { int i = observers.indexOf(observer); if(i >= 0){ observers.remove(i); } } public void notifyObserver() { for(int i=0; i<observers.size(); i++){ Observer observer = observers.get(i); observer.update(team, score); } } public void setMatchData(String team,String score){ this.team = team; this.score = score; notifyObserver(); } private String team; private String score; private List<Observer> observers = new ArrayList<Observer>(); }
Observer實現類TVObserver、WebsitObserver:
public class TVObserver implements Observer{ public TVObserver(Subject subject){ this.subject = subject; this.subject.registObserver(this); } public void update(String team, String score) { this.team = team; this.score = score; this.display(); } public void display(){ System.out.println("現在是TV直播,正在播放的比賽是 : " + team + " 現在的比分是:" + score); } private Subject subject; private String team; private String score; }
public class WebsitObserver implements Observer{
public WebsitObserver(Subject subject){
this.subject = subject;
this.subject.registObserver(this);
}
public void update(String team, String score) {
this.team = team;
this.score = score;
this.display();
}
public void display(){
System.out.println("這裡是比賽直播網站,比賽的最新賽況 : " + team + " 比分 : " + score);
}
private String team;
private String score;
private Subject subject;
}
使用程式碼:
public static void main(String[] args){
MatchData matchData = new MatchData();
Observer websit = new WebsitObserver(matchData);
Observer tvObserver = new TVObserver(matchData);
matchData.setMatchData("西班牙VS巴西", "1:2");
matchData.setMatchData("美國VS英國", "0:1");
matchData.setMatchData("西班牙VS葡萄牙", "1:1");
}
2.裝飾模式
裝飾模式:動態的將責任附加到物件上,若要擴充套件功能,裝飾著提供了比繼承更有彈性的替代方案。
具體的用法用程式碼演示:
定義一個抽象的Food抽象類
public abstract class Food {
public String getDescription() {
return description;
}
protected String description = "Just Rice";
}
定義一個繼承Food的類Rice和Black_kerneled_rice
public class Rice extends Food{
public Rice(){
this.description = "Rice";
}
}
public class Black_kerneled_rice extends Food{
public Black_kerneled_rice(){
this.description = "black kerneled rice";
}
}
裝飾者:
public abstract class Comdiment extends Food{
public abstract String getDescription();
}
繼承自裝飾著的類:
public class Salt extends Comdiment{
public Salt(Food food){
this.food = food;
}
public String getDescription() {
return this.food.getDescription() + " ,salt";
}
private Food food;
}
public class Soy_sauce extends Comdiment{
public Soy_sauce(Food food){
this.food = food;
}
public String getDescription() {
return this.food.getDescription() + " ,soy sauce";
}
private Food food;
}
public class Chicken_essence extends Comdiment{
public Chicken_essence(Food food){
this.food = food;
}
public String getDescription() {
return this.food.getDescription() + " ,chicken essence";
}
private Food food;
}
使用程式碼:
public static void main(String[] args){
/*
* 白米油炒飯 加醬油、鹽、雞精
*/
Food food = new Rice();
food = new Salt(food);
food = new Soy_sauce(food);
food = new Chicken_essence(food);
System.out.println(food.getDescription());
/*
* 黑米炒飯 加鹽、雙份雞精
*/
food = new Black_kerneled_rice();
food = new Salt(food);
food = new Chicken_essence(food);
food = new Chicken_essence(food);
System.out.println(food.getDescription());
}
3.工廠方法模式
工廠方法模式:定義一個建立物件的介面,但由子類決定要是梨花的類是哪一個。工廠方法讓例項化推遲到子類。
具體用一個蛋糕店來演示:
抽象類Cake:
public abstract class Cake {
public String getName() {
return this.name;
}
public abstract void prepare(); // 準備工作
public abstract void bake(); // 烘烤
public abstract void decorate(); // 新增飾品
public abstract void box(); // 裝箱
protected String name;
}
生產蛋糕的工廠:
public abstract class CakeFactory {
public Cake createCake(String name) {
this.cake = this.makeCake(name);
cake.prepare();
cake.bake();
cake.decorate();
cake.box();
return cake;
}
public abstract Cake makeCake(String name);
private Cake cake;
}
雞蛋蛋糕、水果蛋糕:
public class EggCake extends Cake {
public EggCake(String name) {
this.name = name;
}
public void prepare() {
System.out.println("準備麵粉,奶油,雞蛋,甜精");
System.out.println("將麵粉和雞蛋、甜精一起攪拌");
System.out.println("攪拌後做成蛋糕的形狀");
}
public void bake() {
System.out.println("將做好的蛋糕原型放入烤箱烘烤,烤好後就出爐了");
}
public void decorate() {
System.out.println("將烤好後的蛋糕新增奶油、巧克力");
}
public void box() {
System.out.println("將加好奶油的蛋糕裝入蛋糕盒");
}
public String getName() {
return this.name;
}
}
public class FruitCake extends Cake {
public FruitCake(String name) {
this.name = name;
}
public void prepare() {
System.out.println("準備麵粉,奶油,甜精");
System.out.println("將麵粉和甜精一起攪拌");
System.out.println("攪拌後做成蛋糕的形狀");
}
public void bake() {
System.out.println("將做好的蛋糕原型放入烤箱烘烤,烤好後就出爐了");
}
public void decorate() {
System.out.println("將烤好後的蛋糕新增奶油、巧克力和水果片");
}
public void box() {
System.out.println("將加好奶油的蛋糕裝入蛋糕盒");
}
}
雞蛋蛋糕工廠、水果蛋糕工廠:
public class EggCakeFactory extends CakeFactory {
public Cake makeCake(String name) {
return new EggCake(name);
}
}
public class FruitCakeFactory extends CakeFactory {
public Cake makeCake(String name) {
return new FruitCake(name);
}
}
測試程式碼:
public static void main(String[] args) {
CakeFactory cakeFactory = new FruitCakeFactory();
Cake cake = cakeFactory.createCake("草莓蛋糕");
System.out.println(cake.getName());
cakeFactory = new EggCakeFactory();
cake = cakeFactory.createCake("蛋黃蛋糕");
System.out.println(cake.getName());
}
4.抽象工廠模式
抽象工廠模式:提供一個藉口,用於建立相關或依賴物件的家族,而不要明確制定具體類。
還是用蛋糕店的例子來演示:
抽象類Cake:
public abstract class Cake {
protected String name;
protected String cream;
protected String chocolate;
protected String condiments;
public abstract void prepare();
public void bake(){
System.out.println("將蛋糕放進烤箱烘烤");
}
public void decorate(){
System.out.println("將" + condiments + "新增到蛋糕上");
}
public void box(){
System.out.println("將蛋糕裝入包裝箱中");
}
public void makeCake(){
this.prepare();
this.bake();
this.decorate();
this.box();
}
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
}
抽象類CakeStore:
public abstract class CakeStore {
public abstract Cake createCake(String name);
}
抽象原料工廠:
public abstract class IngredientFactory {
public abstract String createCream();
public abstract String createChocolate();
public abstract String createCondiments();
}
Cake的實現類StrawberryCake:
public class StrawberryCake extends Cake{
public StrawberryCake(IngredientFactory ingredientFactory){
this.ingredientFactory = ingredientFactory;
}
public void prepare() {
this.cream = this.ingredientFactory.createCream();
this.chocolate = this.ingredientFactory.createChocolate();
this.condiments = this.ingredientFactory.createCondiments();
}
private IngredientFactory ingredientFactory = null;
}
抽象原料工廠的實現類CreamIngredientFactory:
public class CreamIngredientFactory extends IngredientFactory{
public String createCream() {
return "酸奶冰淇淋";
}
public String createChocolate() {
return "黑巧克力";
}
public String createCondiments() {
return "草莓片、蘋果片、西瓜片、藍莓片、獼猴桃片";
}
}
抽象蛋糕店的實現類XXCakeStore:
public class XXCakeStore extends CakeStore{
public Cake createCake(String name) {
IngredientFactory ingredientFactory = new CreamIngredientFactory();
Cake cake = null;
if("草莓蛋糕".equals(name)){
cake = new StrawberryCake(ingredientFactory);
cake.makeCake();
cake.setName("草莓奶油蛋糕");
return cake;
}else{
//......
}
return null;
}
}
測試程式碼:
public static void main(String[] args) {
Cake cake = new XXCakeStore().createCake("草莓蛋糕");
if(cake != null){
System.out.println(cake.getName());
}
}