<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                第13章 原型模式 13.1 個性化電子賬單 現在電子賬單越來越流行了,比如你的信用卡,每到月初的時候銀行就會發一份電子郵件給你,說你這個月消費了多少,什么時候消費的,積分是多少等,這是每個月發一次。還有一種也是銀行發的郵件你肯定非常有印象:廣告信,現在各大銀行的信用卡部門都在拉攏客戶,電子郵件是一種廉價、快捷的通信方式,你用紙質的廣告信那個費用多高呀,比如我行今天推出一個信用卡刷卡抽獎活動,通過電子賬單系統可以一個晚上發送給600萬客戶,為什么要用電子賬單系統呢?直接找個發垃圾郵件的工具不就解決問題了嗎?是個好主意,但是這個方案在金融行業是行不通的,為什么?因為銀行發送該類郵件是有要求的: ● 個性化服務 一般銀行都要求個性化服務,發過去的郵件上總有一些個人信息吧,比如“××先生”,“××女士”等。 ● 遞送成功率 郵件的遞送成功率有一定的要求,由于大批量地發送郵件會被接收方郵件服務器誤認是垃圾郵件,因此在郵件頭要增加一些偽造數據,以規避被反垃圾郵件引擎誤認為是垃圾郵件。 從這兩方面考慮廣告信的發送也是電子賬單系統(電子賬單系統一般包括:賬單分析、賬單生成器、廣告信管理、發送隊列管理、發送機、退信處理、報表管理等)的一個子功能,我們今天就來考慮一下廣告信這個模塊是怎么開發的。那既然是廣告信,肯定需要一個模板,然后再從數據庫中把客戶的信息一個一個地取出,放到模板中生成一份完整的郵件,然后扔給發送機進行發送處理,類圖如圖13-1所示。 在類圖中AdvTemplate是廣告信的模板,一般都是從數據庫取出,生成一個BO或者是DTO,我們這里使用一個靜態的值來作代表;Mail類是一封郵件類,發送機發送的就是這個類。我們先來看AdvTemplate,如代碼清單13-1所示。 ![](https://box.kancloud.cn/2016-08-14_57b003633350c.jpg) 圖13-1 發送電子賬單類圖 代碼清單13-1 廣告信模板代碼 public?class?AdvTemplate?{ ?????//廣告信名稱 ?????private?String?advSubject?="XX銀行國慶信用卡抽獎活動"; ?????//廣告信內容 ?????private?String?advContext?=?"國慶抽獎活動通知:只要刷卡就送你一百萬!..."; ?????//取得廣告信的名稱 ?????public?String?getAdvSubject(){ ?????????????return?this.advSubject; ?????} ?????//取得廣告信的內容 ?????public?String?getAdvContext(){ ?????????????return?this.advContext; ?????} } 郵件類Mail如代碼清單13-2所示。 代碼清單13-2 郵件類代碼 public?class?Mail?{ ?????//收件人 ?????private?String?receiver; ?????//郵件名稱 ?????private?String?subject; ?????//稱謂 ?????private?String?appellation; ?????//郵件內容 ?????private?String?contxt;????? ?????//郵件的尾部,一般都是加上"XXX版權所有"等信息 ?????private?String?tail; ?????//構造函數 ?????public?Mail(AdvTemplate?advTemplate){ ?????????????this.contxt?=?advTemplate.getAdvContext(); ?????????????this.subject?=?advTemplate.getAdvSubject(); ?????} ?????//以下為getter/setter方法 ?????public?String?getReceiver()?{ ?????????????return?receiver; ?????} ?????public?void?setReceiver(String?receiver)?{ ?????????????this.receiver?=?receiver; ?????} ?????public?String?getSubject()?{ ?????????????return?subject; ?????} ?????public?void?setSubject(String?subject)?{ ?????????????this.subject?=?subject; ?????} ?????public?String?getAppellation()?{ ?????????????return?appellation; ?????} ?????public?void?setAppellation(String?appellation)?{ ?????????????this.appellation?=?appellation; ?????} ?????public?String?getContxt()?{ ?????????????return?contxt; ?????} ?????public?void?setContxt(String?contxt)?{ ?????????????this.contxt?=?contxt; ?????} ?????public?String?getTail()?{ ?????????????return?tail; ?????} ?????public?void?setTail(String?tail)?{ ?????????????this.tail?=?tail; ?????}?? } Mail類就是一個業務對象,雖然比較長,還是比較簡單的。我們再來看業務場景類是如何對郵件繼續處理的,如代碼清單11-3所示。 代碼清單13-3 場景類 public?class?Client?{ ?????//發送賬單的數量,這個值是從數據庫中獲得 ?????private?static?int?MAX_COUNT?=?6; ?????public?static?void?main(String[]?args)?{ ???????????????//模擬發送郵件 ???????????????int?i=0; ???????????????//把模板定義出來,這個是從數據庫中獲得 ???????????????Mail?mail?=?new?Mail(new?AdvTemplate()); ???????????????mail.setTail("XX銀行版權所有"); ???????????????while(i<MAX_COUNT){ ???????????????????????//以下是每封郵件不同的地方 ???????????????????????mail.setAppellation(getRandString(5)+"?先生(女士)"); ???????????????????????mail.setReceiver(getRandString(5)+"@"+getRandString(8)?+".com");? ???????????????????????//然后發送郵件 ???????????????????????sendMail(mail); ???????????????????????i++; ?????????????} ?????}?? ?????//發送郵件 ?????public?static?void?sendMail(Mail?mail){ ?????????????System.out.println("標題:"+mail.getSubject()?+?"\t收件人: ????????????????"+mail.getReceiver()+"\t...發送成功!"); ?????}?? ?????//獲得指定長度的隨機字符串 ?????public?static?String?getRandString(int?maxLength){ ?????????????String?source?="abcdefghijklmnopqrskuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; ?????????????StringBuffer?sb?=?new?StringBuffer(); ?????????????Random?rand?=?new?Random(); ?????????????for(int?i=0;i<maxLength;i++){ ?????????????????????sb.append(source.charAt(rand.nextInt(source.length()))); ?????????????} ?????????????return?sb.toString(); ?????} } 運行結果如下所示: ? | 標題:XX銀行國慶信用卡抽獎活動 |   收件人:fjQUm@ZnkyPSsL.com |  ...發送成功! | |-----|-----|-----| | 標題:XX銀行國慶信用卡抽獎活動 |   收件人:ZIKnC@NOKdloNM.com |  ...發送成功! | | 標題:XX銀行國慶信用卡抽獎活動 |   收件人:zNkMI@HpMMSZaz.com |  ...發送成功! | | 標題:XX銀行國慶信用卡抽獎活動 |   收件人:oMTFA@uBwkRjxa.com |  ...發送成功! | | 標題:XX銀行國慶信用卡抽獎活動 |   收件人:TquWT@TLLVNFja.com |  ...發送成功! | | 標題:XX銀行國慶信用卡抽獎活動 |   收件人:rkQbp@mfATHDQH.com |  ...發送成功! | 由于是隨機數,每次運行都有所差異,不管怎么樣,我們這個電子賬單發送程序是編寫出來了,也能正常發送。我們再來仔細地想想,這個程序是否有問題?Look here,這是一個線程在運行,也就是你發送的是單線程的,那按照一封郵件發出去需要0.02秒(夠小了,你還要到數據庫中取數據呢),600萬封郵件需要33個小時,也就是一個整天都發送不完,今天的沒發送完,明天的賬單又產生了,日積月累,激起甲方人員一堆抱怨,那怎么辦? 好辦,把sendMail修改為多線程,但是只把sendMail修改為多線程還是有問題的呀,產生第一封郵件對象,放到線程1中運行,還沒有發送出去;線程2也啟動了,直接就把郵件對象mail的收件人地址和稱謂修改掉了,線程不安全了。說到這里,你會說這有N多種解決辦法,其中一種是使用一種新型模式來解決這個問題:通過對象的復制功能來解決這個問題,類圖稍做修改,如圖13-2所示。 ![](https://box.kancloud.cn/2016-08-14_57b00363498e1.jpg) 圖13-2 修改后的發送電子賬單類圖 增加了一個Cloneable接口(Java自帶的一個接口), Mail實現了這個接口,在Mail類中覆寫clone()方法,我們來看Mail類的改變,如代碼清單13-4所示。 代碼清單13-4 修改后的郵件類 public?class?Mail?implements?Cloneable{???? ?????//收件人 ?????private?String?receiver; ?????//郵件名稱 ?????private?String?subject; ?????//稱謂 ?????private?String?appellation; ?????//郵件內容 ?????private?String?contxt;????? ?????//郵件的尾部,一般都是加上"XXX版權所有"等信息 ?????private?String?tail; ?????//構造函數 ?????public?Mail(AdvTemplate?advTemplate){ ?????????????this.contxt?=?advTemplate.getAdvContext(); ?????????????this.subject?=?advTemplate.getAdvSubject(); ?????} ?????@Override ?????public?Mail?clone(){ ?????????????Mail?mail?=null; ?????????????try?{ ????????????????????mail?=?(Mail)super.clone(); ?????????????}?catch?(CloneNotSupportedException?e)?{ ????????????????????//?TODO?Auto-generated?catch?block ????????????????????e.printStackTrace(); ?????????????} ?????????????return?mail; ?????} ?????//以下為getter/setter方法 ?????public?String?getReceiver()?{ ?????????????return?receiver; ?????} ?????public?void?setReceiver(String?receiver)?{ ?????????????this.receiver?=?receiver; ?????} ?????public?String?getSubject()?{ ?????????????return?subject; ?????} ?????public?void?setSubject(String?subject)?{ ?????????????this.subject?=?subject; ?????} ?????public?String?getAppellation()?{ ?????????????return?appellation; ?????} ?????public?void?setAppellation(String?appellation)?{ ?????????????this.appellation?=?appellation; ?????} ?????public?String?getContxt()?{ ?????????????return?contxt; ?????} ?????public?void?setContxt(String?contxt)?{ ?????????????this.contxt?=?contxt; ?????} ?????public?String?getTail()?{ ?????????????return?tail; ?????} ?????public?void?setTail(String?tail)?{ ?????????????this.tail?=?tail; ?????}?? } 注意看粗體部分,實現了一個接口,并重寫了clone方法,大家可能看著這個類有點奇怪,先保留你的好奇,我們繼續講下去,稍后會給你清晰的答案。我們再來看場景Client的變化,如代碼清單13-5所示。 代碼清單13-5 修改后的場景類 public?class?Client?{ ?????//發送賬單的數量,這個值是從數據庫中獲得 ?????private?static?int?MAX_COUNT?=?6; ?????public?static?void?main(String[]?args)?{ ?????????????//模擬發送郵件 ?????????????int?i=0; ?????????????//把模板定義出來,這個是從數據中獲得 ?????????????Mail?mail?=?new?Mail(new?AdvTemplate()); ?????????????mail.setTail("XX銀行版權所有"); ?????????????while(i<MAX_COUNT){ ????????????????????//以下是每封郵件不同的地方 ????????????????????Mail?cloneMail?=?mail.clone(); ????????????????????cloneMail.setAppellation(getRandString(5)+"?先生(女士)"); ????????????????????cloneMail.setReceiver(getRandString(5)+"@"+getRandString(8)+".com"); ????????????????????//然后發送郵件 ????????????????????sendMail(cloneMail); ????????????????????i++; ?????????????} ?????} } 運行結果不變,一樣完成了電子廣告信的發送功能,而且sendMail即使是多線程也沒有關系。注意,看Client類中的粗體字mail.clone()這個方法,把對象復制一份,產生一個新的對象,和原有對象一樣,然后再修改細節的數據,如設置稱謂、設置收件人地址等。這種不通過new關鍵字來產生一個對象,而是通過對象復制來實現的模式就叫做原型模式。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看