java中策略設計模式_Java中的設計模式(五):策略模式

策略設計模式是行為設計模式之一。當我們為特定任務使用多個算法時,使用策略模式,客戶端決定在運行時使用的實際實現。

7139

策略模式的最佳示例之一是Collections.sort()采用Comparator參數的方法。基于Comparator接口的不同實現,對象將以不同的方式進行排序。

2|0實例

對于我們的示例,我們將嘗試實施一個簡單的購物車,我們有兩種付款策略 - 使用信用卡或使用PayPal。

首先,我們將為我們的策略模式示例創建接口,在我們的例子中,支付金額作為參數傳遞。

支付方式:PaymentStrategy.javapackage com.journaldev.design.strategy;

public interface PaymentStrategy {

public void pay(int amount);

}

現在我們將不得不使用信用卡/借記卡或通過PayPal為支付創建具體的算法實現。

信用卡付款:CreditCardStrategy.javapackage com.journaldev.design.strategy;

public class CreditCardStrategy implements PaymentStrategy {

private String name;

private String cardNumber;

private String cvv;

private String dateOfExpiry;

public CreditCardStrategy(String nm, String ccNum, String cvv, String expiryDate){

this.name=nm;

this.cardNumber=ccNum;

this.cvv=cvv;

this.dateOfExpiry=expiryDate;

}

@Override

public void pay(int amount) {

System.out.println(amount +" paid with credit/debit card");

}

}

Paypal付款:PaypalStrategy.javapackage com.journaldev.design.strategy;

public class PaypalStrategy implements PaymentStrategy {

private String emailId;

private String password;

public PaypalStrategy(String email, String pwd){

this.emailId=email;

this.password=pwd;

}

@Override

public void pay(int amount) {

System.out.println(amount + " paid using Paypal.");

}

}

現在我們的策略模式示例算法準備好了。我們可以實施購物車和付款方式將需要輸入作為付款策略。package com.journaldev.design.strategy;

public class Item {

private String upcCode;

private int price;

public Item(String upc, int cost){

this.upcCode=upc;

this.price=cost;

}

public String getUpcCode() {

return upcCode;

}

public int getPrice() {

return price;

}

}

ShoppingCart.javapackage com.journaldev.design.strategy;

import java.text.DecimalFormat;

import java.util.ArrayList;

import java.util.List;

public class ShoppingCart {

//List of items

List items;

public ShoppingCart(){

this.items=new ArrayList();

}

public void addItem(Item item){

this.items.add(item);

}

public void removeItem(Item item){

this.items.remove(item);

}

public int calculateTotal(){

int sum = 0;

for(Item item : items){

sum += item.getPrice();

}

return sum;

}

public void pay(PaymentStrategy paymentMethod){

int amount = calculateTotal();

paymentMethod.pay(amount);

}

}

請注意,購物車的付款方式需要付款算法作為參數,并且不會將其作為實例變量存儲在任何位置。

讓我們用一個簡單的程序測試我們的策略模式示例設置。

ShoppingCartTest.javapackage com.journaldev.design.strategy;

public class ShoppingCartTest {

public static void main(String[] args) {

ShoppingCart cart = new ShoppingCart();

Item item1 = new Item("1234",10);

Item item2 = new Item("5678",40);

cart.addItem(item1);

cart.addItem(item2);

//pay by paypal

cart.pay(new PaypalStrategy("myemail@example.com", "mypwd"));

//pay by credit card

cart.pay(new CreditCardStrategy("Pankaj Kumar", "1234567890123456", "786", "12/15"));

}

}

上述程序的輸出是:50 paid using Paypal.

50 paid with credit/debit card

3|0類圖

7139

4|0總結

我們可以使用組合為策略創建實例變量,但我們應該避免這種情況,因為我們希望將特定策略應用于特定任務。在Collections.sort()和Arrays.sort()方法中遵循相同的方法,將比較器作為參數。

策略模式與狀態模式(State Pattern)非常相似。其中一個區別是Context包含狀態作為實例變量,并且可以有多個任務,其實現可以依賴于狀態,而策略模式策略作為參數傳遞給方法,上下文對象沒有任何變量來存儲它。

當我們為特定任務提供多個算法時,策略模式很有用,我們希望我們的應用程序可以靈活地在運行時為特定任務選擇任何算法。

優點:1、算法可以自由切換。 2、避免使用多重條件判斷。 3、擴展性良好。

缺點:1、策略類會增多。 2、所有策略類都需要對外暴露。

主要解決:在有多種算法相似的情況下,使用 if...else 所帶來的復雜和難以維護。

何時使用:一個系統有許多許多類,而區分它們的只是他們直接的行為。

如何解決:將這些算法封裝成一個一個的類,任意地替換。

關鍵代碼:實現同一個接口。

使用場景: 1、如果在一個系統里面有許多類,它們之間的區別僅在于它們的行為,那么使用策略模式可以動態地讓一個對象在許多行為中選擇一種行為。 2、一個系統需要動態地在幾種算法中選擇一種。 3、如果一個對象有很多的行為,如果不用恰當的模式,這些行為就只好使用多重的條件選擇語句來實現。

注意事項:如果一個系統的策略多于四個,就需要考慮使用混合模式,解決策略類膨脹的問題。

這就是java中的Strategy Pattern,我希望你喜歡它。

翻譯于:strategy-design-pattern-in-java

__EOF__

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/272752.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/272752.shtml
英文地址,請注明出處:http://en.pswp.cn/news/272752.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

isset函數

isset (PHP 4, PHP 5) isset — 檢測變量是否設置 檢測變量是否設置,并且不是 NULL。 如果 var 存在并且值不是 NULL 則返回 TRUE,否則返回 FALSE。 $a "test"; $b "anothertest";var_dump(isset($a)); // TRUE var_dump(i…

SQLl中的left join、right join、inner join詳解

left join(左聯接) 返回包括左表中的所有記錄和右表中聯結字段相等的記錄right join(右聯接) 返回包括右表中的所有記錄和左表中聯結字段相等的記錄inner join(等值連接) 只返回兩個表中聯結字段相等的行舉例如下:--------------------------------------------表A記…

afudos備份bios不動_bios刷壞后的兩種解決方法

通常主板新的BIOS可以修正舊版中BIOS的一些BUG,糾正對某些硬件和軟件的兼容問題,添加新硬件的支持等等,所以有時我們需要刷新BIOS。但刷新主板BIOS實際上是存在一定風險的,雖然現在各主板廠商都推出了在Windows下刷新BIOS的軟件&a…

光學基礎知識:白光、顏色混合、RGB、色彩空間

1665年,牛頓(Isaac Newton)進行了太陽光實驗,讓太陽光通過窗板的小圓孔照射在玻璃三角棱鏡上,光束在棱鏡中折射后,擴散為一個連續的彩虹顏色帶,牛頓稱之為光譜,表示連續的可見光譜。而可見光譜只是所有電磁…

SQL Server各個版本功能比較

微軟的SQlserver主要經歷了從sql server 2000 到最新的sql server 2017,現把各個版本的更新特性介紹如下:SQL SERVER 2000日志傳送索引視圖SQL SERVER 2005數據庫鏡像(只有 SQL Server 2005 Enterprise Edition SP1 和更高版本支持異步數據庫…

java hibernate的使用_《Hibernate快速開始 – 4 – 使用JAVA持久層 API (JPA)教程》

章節目標使用JPA EntityManagerFactory使用注解提供映射信息使用 JPA 接口本教程可在 entitymanger/ 路徑下下載4.1. persistence.xml之前的章節使用了hibernate原生的配置文件hibernate.cfg.xml。然而,JPA中定義了不同的的自助配置文件persistence.xml。這個啟動過…

HTTP消息中Header頭部信息整理

1、HTTP請求方式GET向Web服務器請求一個文件POST向Web服務器發送數據讓Web服務器進行處理PUT向Web服務器發送數據并存儲在Web服務器內部HEAD檢查一個對象是否存在DELETE從Web服務器上刪除一個文件CONNECT對通道提供支持TRACE跟蹤到服務器的路徑OPTIONS查詢Web服務器的性能說明&…

gdb命令中attach使用

[測試程序] 我們先看看我們的測試程序: /* in eg1.c */ int wib(int no1, int no2) { int result, diff; diff no1 - no2; result no1 / diff; return result; } int main() { pid_t pid; pid fork(); if (pid &…

java%4d_java積累

數組的使用package javaDemo;import java.util.*;/**** author Administrator* version 1.0***/public class test {public static void main(String[] args){String[] greeting new String[3];greeting[0] "Welcome to Core Java";greeting[1] "by Cay Hors…

查詢CPU占用高的SQL語句的解決方案

觸發器造成死鎖、作業多且頻繁、中間表的大量使用、游標的大量使用、索引的設計不合理、事務操作頻繁、SQL語句設計不合理,都會造成查詢效率低下、影響服務器性能的發揮。我們可以使用sql server自帶的性能分析追蹤工具sql profiler分析數據庫設計所產生問題的來源&…

父類與子類之間的關系

1) 運行課件中的例題ParentChildTest.java,回答下列問題: a) 左邊的程序運行結果是什么? b) 你如何解釋會得到這樣的輸出? 第一個創建一個Parent對象,調用的是父類構造方法 第二個創建一個Child對象,調用的…

php獲取到的json數據如何處理_php – 如何從API獲取JSON數據

我使用過雅虎的符號查找它以JSON格式返回數據.喜歡以下YAHOO.Finance.SymbolSuggest.ssCallback({"ResultSet": {"Query": "ya","Result": [{"symbol": "YHOO","name": "Yahoo! Inc.","…

.NET開發中應該遵循的幾點建議

1、始終控制類的大小那些超大的類在嘗試做太多的事情,這違反了單一職責原則, 為什么一定要將兩個職責分離到單獨的類中呢?因為每一個職責都是變化的中心。在需求變更時,這個變更將會出現在負責該職責的類中。如果一個類承擔了多個…

Linux下jetty報java.lang.OutOfMemoryError: PermGen space及Jetty內存配置調優解決方案

Linux下的jetty報java.lang.OutOfMemoryError: PermGen space及Jetty內存配置調優解決方案問題linux的jetty下發布程序后再啟動jetty服務時,發現啟動不了,從日志中找到報java.lang.OutOfMemoryError: PermGen space。原因分析PermGen space,全…

微博php sdk,手機第三方新浪微博登錄php api實現分析

提供api,POST方式,根據傳遞過來的微博uid/appkey,判斷該用戶的ID是否在自己的數據庫中。如果有,直接登錄返回用戶登錄api的json。如果沒有,就將該用戶的IDtoken請求微博用戶信息api:http://open.weibo.com/…

13條只有程序員才能懂的內涵段子

一、bug跟蚊子的相似之處:1、不知道藏在哪里。2、不知道有多少。3、總是在你即將睡覺休息的時候出現。二、A:最近在看《一拳超人》,覺得咱們程序猿跟埼玉老師有點像啊!B:哪里像了?A:越禿越強&am…

Posix消息隊列

一、函數 mq_open 頭文件 mqueue.h; 原型 mqd_t mq_open(const char *name, int oflag, .../*mode_t mode,struct mq_attr* attr*/); 函數功能 創建消息隊列; 參數 name :消息隊列的名字,根據消息隊列的規則,為了更好的…

php 等值線,【地理】攻克等值線的六大法門

3.等值線數值大小的判斷方法(1)通常情況下,據圖中已標注的等值線進行分析標注,標注時注意:①等值線數值的遞變規律;②相鄰兩條等值線差值的大小。(2)在閉合的等值線上,除據以上方法判斷外,還可用“大于…

4步win7下簡單FTP服務器搭建(試驗成功)

本文介紹通過win7自帶的IIS來搭建一個只能實現基本功能的FTP服務器,第一次裝好WIN7后我愣是沒整出來,后來查了一下網上資料經過試驗后搭建成功,其實原理和步驟與windows前期的版本差不多,主要是對新的操作系統還不是很熟悉。相信用…

C#開發模式——單例模式

一、單例模式簡介單例模式是為保證一個對象,在程序運行的任何時刻只有一個實例存在,我們把這種實現方式稱之為“單例模式”。二、單例模式的核心單例類只有一個實例存在單例類提供一個全局訪問點單例類通過自己創建唯一實例單例類對外所有訪問對象都提供一個唯一實例…