java real football_Java学习--设计模式之行为型模式(三)
一、空對(duì)象模式(Null Object Pattern)
1、概念
在空對(duì)象模式(Null Object Pattern)中,一個(gè)空對(duì)象取代 NULL 對(duì)象實(shí)例的檢查。Null 對(duì)象不是檢查空值,而是反應(yīng)一個(gè)不做任何動(dòng)作的關(guān)系。這樣的 Null 對(duì)象也可以在數(shù)據(jù)不可用的時(shí)候提供默認(rèn)的行為。在空對(duì)象模式中,我們創(chuàng)建一個(gè)指定各種要執(zhí)行的操作的抽象類(lèi)和擴(kuò)展該類(lèi)的實(shí)體類(lèi),還創(chuàng)建一個(gè)未對(duì)該類(lèi)做任何實(shí)現(xiàn)的空對(duì)象類(lèi),該空對(duì)象類(lèi)將無(wú)縫地使用在需要檢查空值的地方。
2、實(shí)例
我們將創(chuàng)建一個(gè)定義操作(在這里,是客戶(hù)的名稱(chēng))的?AbstractCustomer?抽象類(lèi),和擴(kuò)展了?AbstractCustomer?類(lèi)的實(shí)體類(lèi)。工廠類(lèi)?CustomerFactory?基于客戶(hù)傳遞的名字來(lái)返回?RealCustomer?或?NullCustomer?對(duì)象。演示類(lèi)?NullPatternDemo,我們的演示類(lèi)使用?CustomerFactory?來(lái)演示空對(duì)象模式的用法。
(1)、創(chuàng)建一個(gè)抽象類(lèi)
public abstract classAbstractCustomer {protectedString name;public abstract booleanisNil();public abstractString getName();
}
(2)、擴(kuò)展一個(gè)執(zhí)行操作的實(shí)體類(lèi)
public class RealCustomer extendsAbstractCustomer {publicRealCustomer(String name) {this.name =name;
}
@OverridepublicString getName() {returnname;
}
@Overridepublic booleanisNil() {return false;
}
}
(3)、擴(kuò)展一個(gè)不做任何實(shí)現(xiàn)的空對(duì)象類(lèi)
public class NullCustomer extendsAbstractCustomer {
@OverridepublicString getName() {return "Not Available in Customer Database";
}
@Overridepublic booleanisNil() {return true;
}
}
(4)、創(chuàng)建?CustomerFactory?類(lèi)
public classCustomerFactory {public static final String[] names = {"Rob", "Joe", "Julie"};public staticAbstractCustomer getCustomer(String name){for (int i = 0; i < names.length; i++) {if(names[i].equalsIgnoreCase(name)){return newRealCustomer(name);
}
}return newNullCustomer();
}
}
(5)、使用?CustomerFactory,基于客戶(hù)傳遞的名字,來(lái)獲取?RealCustomer?或?NullCustomer?對(duì)象
public classNullPatternDemo {public static voidmain(String[] args) {
AbstractCustomer customer1= CustomerFactory.getCustomer("Rob");
AbstractCustomer customer2= CustomerFactory.getCustomer("Bob");
AbstractCustomer customer3= CustomerFactory.getCustomer("Julie");
AbstractCustomer customer4= CustomerFactory.getCustomer("Laura");
System.out.println("Customers");
System.out.println(customer1.getName());
System.out.println(customer2.getName());
System.out.println(customer3.getName());
System.out.println(customer4.getName());
}
}
(5)、演示結(jié)果
1 Customers2 Rob3 Not Available in Customer Database4 Julie5 Not Available in Customer Database
二、策略模式(Strategy Pattern)
1、概念
在策略模式(Strategy Pattern)中,一個(gè)類(lèi)的行為或其算法可以在運(yùn)行時(shí)更改。這種類(lèi)型的設(shè)計(jì)模式屬于行為型模式。
2、簡(jiǎn)介
意圖:定義一系列的算法,把它們一個(gè)個(gè)封裝起來(lái), 并且使它們可相互替換。
主要解決:在有多種算法相似的情況下,使用 if...else 所帶來(lái)的復(fù)雜和難以維護(hù)。
何時(shí)使用:一個(gè)系統(tǒng)有許多許多類(lèi),而區(qū)分它們的只是他們直接的行為。
如何解決:將這些算法封裝成一個(gè)一個(gè)的類(lèi),任意地替換。
關(guān)鍵代碼:實(shí)現(xiàn)同一個(gè)接口。
優(yōu)點(diǎn):
(1)、算法可以自由切換。
(2)、避免使用多重條件判斷。
(3)、擴(kuò)展性良好。
缺點(diǎn):
(1)、策略類(lèi)會(huì)增多。
(2)、所有策略類(lèi)都需要對(duì)外暴露。
使用場(chǎng)景:
(1)、如果在一個(gè)系統(tǒng)里面有許多類(lèi),它們之間的區(qū)別僅在于它們的行為,那么使用策略模式可以動(dòng)態(tài)地讓一個(gè)對(duì)象在許多行為中選擇一種行為。
(2)、一個(gè)系統(tǒng)需要?jiǎng)討B(tài)地在幾種算法中選擇一種。
(3)、如果一個(gè)對(duì)象有很多的行為,如果不用恰當(dāng)?shù)哪J?#xff0c;這些行為就只好使用多重的條件選擇語(yǔ)句來(lái)實(shí)現(xiàn)。
注意事項(xiàng):如果一個(gè)系統(tǒng)的策略多于四個(gè),就需要考慮使用混合模式,解決策略類(lèi)膨脹的問(wèn)題。
3、實(shí)例
我們將創(chuàng)建一個(gè)定義活動(dòng)的?Strategy?接口和實(shí)現(xiàn)了?Strategy?接口的實(shí)體策略類(lèi)。Context?是一個(gè)使用了某種策略的類(lèi)。演示類(lèi)?StrategyPatternDemo,我們的演示類(lèi)使用?Context?和策略對(duì)象來(lái)演示 Context 在它所配置或使用的策略改變時(shí)的行為變化。
(1)、創(chuàng)建一個(gè)接口
public interfaceStrategy {public int doOperation(int num1, intnum2);
}
(2)、創(chuàng)建接口的實(shí)現(xiàn)類(lèi)
public class OperationAdd implementsStrategy{
@Overridepublic int doOperation(int num1, intnum2) {return num1 +num2;
}
}
public class OperationSubstract implementsStrategy{
@Overridepublic int doOperation(int num1, intnum2) {return num1 -num2;
}
}
public class OperationMultiply implementsStrategy{
@Overridepublic int doOperation(int num1, intnum2) {return num1 *num2;
}
}
(3)、創(chuàng)建 Context 類(lèi)
public classContext {privateStrategy strategy;publicContext(Strategy strategy){this.strategy =strategy;
}public int executeStrategy(int num1, intnum2){returnstrategy.doOperation(num1, num2);
}
}
(4)、使用?Context?來(lái)查看當(dāng)它改變策略?Strategy?時(shí)的行為變化。
public classStrategyPatternDemo {public static voidmain(String[] args) {
Context context= new Context(newOperationAdd());
System.out.println("10 + 5 = " + context.executeStrategy(10, 5));
context= new Context(newOperationSubstract());
System.out.println("10 - 5 = " + context.executeStrategy(10, 5));
context= new Context(newOperationMultiply());
System.out.println("10 * 5 = " + context.executeStrategy(10, 5));
}
}
(5)、演示結(jié)果
1 10 + 5 = 15
2 10 - 5 = 5
3 10 * 5 = 50
三、模板模式(Template Pattern)
1、概念
在模板模式(Template Pattern)中,一個(gè)抽象類(lèi)公開(kāi)定義了執(zhí)行它的方法的方式/模板。它的子類(lèi)可以按需要重寫(xiě)方法實(shí)現(xiàn),但調(diào)用將以抽象類(lèi)中定義的方式進(jìn)行。這種類(lèi)型的設(shè)計(jì)模式屬于行為型模式。
2、簡(jiǎn)介
意圖:定義一個(gè)操作中的算法的骨架,而將一些步驟延遲到子類(lèi)中。模板方法使得子類(lèi)可以不改變一個(gè)算法的結(jié)構(gòu)即可重定義該算法的某些特定步驟。
主要解決:一些方法通用,卻在每一個(gè)子類(lèi)都重新寫(xiě)了這一方法。
何時(shí)使用:有一些通用的方法。
如何解決:將這些通用算法抽象出來(lái)。
關(guān)鍵代碼:在抽象類(lèi)實(shí)現(xiàn),其他步驟在子類(lèi)實(shí)現(xiàn)。
優(yōu)點(diǎn):
(1)、封裝不變部分,擴(kuò)展可變部分。
(2)、提取公共代碼,便于維護(hù)。
(3)、行為由父類(lèi)控制,子類(lèi)實(shí)現(xiàn)。
缺點(diǎn):每一個(gè)不同的實(shí)現(xiàn)都需要一個(gè)子類(lèi)來(lái)實(shí)現(xiàn),導(dǎo)致類(lèi)的個(gè)數(shù)增加,使得系統(tǒng)更加龐大。
使用場(chǎng)景:
(1)、有多個(gè)子類(lèi)共有的方法,且邏輯相同。
(2)、重要的、復(fù)雜的方法,可以考慮作為模板方法。
注意事項(xiàng):為防止惡意操作,一般模板方法都加上 final 關(guān)鍵詞。
3、實(shí)例
我們將創(chuàng)建一個(gè)定義操作的?Game?抽象類(lèi),其中,模板方法設(shè)置為 final,這樣它就不會(huì)被重寫(xiě)。Cricket?和?Football?是擴(kuò)展了?Game?的實(shí)體類(lèi),它們重寫(xiě)了抽象類(lèi)的方法。演示類(lèi) TemplatePatternDemo,我們的演示類(lèi)使用?Game?來(lái)演示模板模式的用法。
(1)、創(chuàng)建一個(gè)抽象類(lèi),將他的模板方法設(shè)置為 final
public abstract classGame {abstract voidinitialize();abstract voidstartPlay();abstract voidendPlay();//模板
public final voidplay(){//初始化游戲
initialize();//開(kāi)始游戲
startPlay();//結(jié)束游戲
endPlay();
}
}
(2)、創(chuàng)建實(shí)體游戲類(lèi)
public class Cricket extendsGame {
@OverridevoidendPlay() {
System.out.println("Cricket Game Finished!");
}
@Overridevoidinitialize() {
System.out.println("Cricket Game Initialized! Start playing.");
}
@OverridevoidstartPlay() {
System.out.println("Cricket Game Started. Enjoy the game!");
}
}
public class Football extendsGame {
@OverridevoidendPlay() {
System.out.println("Football Game Finished!");
}
@Overridevoidinitialize() {
System.out.println("Football Game Initialized! Start playing.");
}
@OverridevoidstartPlay() {
System.out.println("Football Game Started. Enjoy the game!");
}
}
(3)、使用?Game?的模板方法 play() 來(lái)演示游戲的定義方式。
public classTemplatePatternDemo {public static voidmain(String[] args) {
Game game= newCricket();
game.play();
System.out.println();
game= newFootball();
game.play();
}
}
(4)、演示結(jié)果
1 Cricket Game Initialized!Start playing.2 Cricket Game Started. Enjoy the game!
3 Cricket Game Finished!
4
5 Football Game Initialized!Start playing.6 Football Game Started. Enjoy the game!
7 Football Game Finished!
四、訪(fǎng)問(wèn)者模式(Visitor Pattern)
1、概念
在訪(fǎng)問(wèn)者模式(Visitor Pattern)中,我們使用了一個(gè)訪(fǎng)問(wèn)者類(lèi),它改變了元素類(lèi)的執(zhí)行算法。通過(guò)這種方式,元素的執(zhí)行算法可以隨著訪(fǎng)問(wèn)者改變而改變。這種類(lèi)型的設(shè)計(jì)模式屬于行為型模式。根據(jù)模式,元素對(duì)象已接受訪(fǎng)問(wèn)者對(duì)象,這樣訪(fǎng)問(wèn)者對(duì)象就可以處理元素對(duì)象上的操作。
2、簡(jiǎn)介
意圖:主要將數(shù)據(jù)結(jié)構(gòu)與數(shù)據(jù)操作分離。
主要解決:穩(wěn)定的數(shù)據(jù)結(jié)構(gòu)和易變的操作耦合問(wèn)題。
何時(shí)使用:需要對(duì)一個(gè)對(duì)象結(jié)構(gòu)中的對(duì)象進(jìn)行很多不同的并且不相關(guān)的操作,而需要避免讓這些操作"污染"這些對(duì)象的類(lèi),使用訪(fǎng)問(wèn)者模式將這些封裝到類(lèi)中。
如何解決:在被訪(fǎng)問(wèn)的類(lèi)里面加一個(gè)對(duì)外提供接待訪(fǎng)問(wèn)者的接口。
關(guān)鍵代碼:在數(shù)據(jù)基礎(chǔ)類(lèi)里面有一個(gè)方法接受訪(fǎng)問(wèn)者,將自身引用傳入訪(fǎng)問(wèn)者。
應(yīng)用實(shí)例:您在朋友家做客,您是訪(fǎng)問(wèn)者,朋友接受您的訪(fǎng)問(wèn),您通過(guò)朋友的描述,然后對(duì)朋友的描述做出一個(gè)判斷,這就是訪(fǎng)問(wèn)者模式。
優(yōu)點(diǎn):
(1)、符合單一職責(zé)原則。
(2)、優(yōu)秀的擴(kuò)展性。
(3)、靈活性。
缺點(diǎn):
(1)、具體元素對(duì)訪(fǎng)問(wèn)者公布細(xì)節(jié),違反了迪米特原則。
(2)、具體元素變更比較困難。
(3)、違反了依賴(lài)倒置原則,依賴(lài)了具體類(lèi),沒(méi)有依賴(lài)抽象。
使用場(chǎng)景:
(1)、對(duì)象結(jié)構(gòu)中對(duì)象對(duì)應(yīng)的類(lèi)很少改變,但經(jīng)常需要在此對(duì)象結(jié)構(gòu)上定義新的操作。
(2)、需要對(duì)一個(gè)對(duì)象結(jié)構(gòu)中的對(duì)象進(jìn)行很多不同的并且不相關(guān)的操作,而需要避免讓這些操作"污染"這些對(duì)象的類(lèi),也不希望在增加新操作時(shí)修改這些類(lèi)。
注意事項(xiàng):訪(fǎng)問(wèn)者可以對(duì)功能進(jìn)行統(tǒng)一,可以做報(bào)表、UI、攔截器與過(guò)濾器。
3、實(shí)例
我們將創(chuàng)建一個(gè)定義接受操作的?ComputerPart?接口。Keyboard、Mouse、Monitor?和?Computer?是實(shí)現(xiàn)了?ComputerPart?接口的實(shí)體類(lèi)。我們將定義另一個(gè)接口?ComputerPartVisitor,它定義了訪(fǎng)問(wèn)者類(lèi)的操作。Computer?使用實(shí)體訪(fǎng)問(wèn)者來(lái)執(zhí)行相應(yīng)的動(dòng)作。演示類(lèi)?VisitorPatternDemo,我們的演示類(lèi)使用?Computer、ComputerPartVisitor?類(lèi)來(lái)演示訪(fǎng)問(wèn)者模式的用法。
(1)、定義一個(gè)表示元素的接口
public interfaceComputerPart {public voidaccept(ComputerPartVisitor computerPartVisitor);
}
(2)、擴(kuò)展不同訪(fǎng)問(wèn)的實(shí)體類(lèi)
public class Keyboard implementsComputerPart {
@Overridepublic voidaccept(ComputerPartVisitor computerPartVisitor) {
computerPartVisitor.visit(this);
}
}
public class Monitor implementsComputerPart {
@Overridepublic voidaccept(ComputerPartVisitor computerPartVisitor) {
computerPartVisitor.visit(this);
}
}
public class Mouse implementsComputerPart {
@Overridepublic voidaccept(ComputerPartVisitor computerPartVisitor) {
computerPartVisitor.visit(this);
}
}
public class Computer implementsComputerPart {
ComputerPart[] parts;publicComputer(){
parts= new ComputerPart[] {new Mouse(), new Keyboard(), newMonitor()};
}
@Overridepublic voidaccept(ComputerPartVisitor computerPartVisitor) {for (int i = 0; i < parts.length; i++) {
parts[i].accept(computerPartVisitor);
}
computerPartVisitor.visit(this);
}
}
(3)、定義一個(gè)表示訪(fǎng)問(wèn)者的接口
public interfaceComputerPartVisitor {public voidvisit(Computer computer);public voidvisit(Mouse mouse);public voidvisit(Keyboard keyboard);public voidvisit(Monitor monitor);
}
(4)、創(chuàng)建實(shí)現(xiàn)了上述類(lèi)的實(shí)體訪(fǎng)問(wèn)者
public class ComputerPartDisplayVisitor implementsComputerPartVisitor {
@Overridepublic voidvisit(Computer computer) {
System.out.println("Displaying Computer.");
}
@Overridepublic voidvisit(Mouse mouse) {
System.out.println("Displaying Mouse.");
}
@Overridepublic voidvisit(Keyboard keyboard) {
System.out.println("Displaying Keyboard.");
}
@Overridepublic voidvisit(Monitor monitor) {
System.out.println("Displaying Monitor.");
}
}
(5)、使用?ComputerPartDisplayVisitor?來(lái)顯示?Computer?的組成部分。
public classVisitorPatternDemo {public static voidmain(String[] args) {
ComputerPart computer= newComputer();
computer.accept(newComputerPartDisplayVisitor());
}
}
(6)、演示結(jié)果
1 Displaying Mouse.2 Displaying Keyboard.3 Displaying Monitor.4 Displaying Computer.
行為型模式的介紹就到這里了,如有誤,還請(qǐng)各位大佬指正;
總結(jié)
以上是生活随笔為你收集整理的java real football_Java学习--设计模式之行为型模式(三)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: mysql 分时统计_mysql中数据统
- 下一篇: java如何做测试数据库_如何模拟用于测