programmer's home, welcome here!

          technical issues and my life

          常用鏈接

          統計

          最新評論

          2007年4月12日 #

          修復注冊表-修復msconfig, regedit

          ---轉自網絡

          運行cmd regedit msconfig提示找不到文件

          今天我同學的電腦,開始運行“cmd regedit msconfig” 這三個命令都不行 ,提示"找不到文件"。可是文件明明在阿。

          直接運行system32目錄下的cmd也不行,照樣提示"找不到文件"。把cmd改名為cmd1就能夠運行

          我的處理過程:

          開始我懷疑是中病毒了,是病毒程序在監聽哪個程序標題為“cmd”,發現就結束。

          首先用卡巴掃了一下啟動項,沒發現病毒。又用冰刃查了一下啟動項,進程,都沒問題。

          想了想會不會中了rootkit 級的馬兒,可用冰刃仔細看了看內核,沒有顯示紅色的阿,剛才殺毒軟件也沒報,是的可能性就不怎么大了。

          那會不會是這個文件遭病毒感染了,我最討厭感染型的蠕蟲病毒了。我從我自己的電腦上把才cmd.exe拷貝過來了,用軟件比較了下(光看大小不行的),一樣的。

          下載文件Hash.zip (28.61 KB , 下載:6次)

          ----------------------------------------------------------------------------

          文件: C:WINDOWSsystem32cmd.exe
          大小: 470528 字節
          文件版本: 5.1.2600.2180 (xpsp_sp2_rtm.040803-2158)
          修改時間: 2005年12月15日, 8:00:00
          MD5: 722A247ACB86960A708528120759266D
          SHA1: A859B7173FB0B1786BE07B01F779725EDF9043E7
          CRC32: 15544920

          ----------------------------------------------------------------------------- 

          后來經過詢問前幾天中過病毒,會不會是上次病毒修改了注冊表什么地方,雖然病毒是被殺了,但是修改的地方仍然沒有改過來的呢。結果證明,這個判斷是正確的。

          具體處理方法:

           用冰刃的修改注冊表,或者將windeows目錄下的regedit.exe修改一下名字,比如叫regedit1.exe,修改注冊表。

          將HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows NTCurrentVersionImage File Execution Options  里面的

          cmd.exe
          msconfig.exe
          regedit.exe
          regedit32.exe

          刪除就可以了。

          典型的 映像劫持。

          這只是處理病毒后遺癥,具體的處理病毒的方法沒有寫,因為有很多病毒都會造成這種狀況,具體病毒具體對待。

          posted @ 2007-05-12 16:25 crazy zerlot 閱讀(1988) | 評論 (0)編輯 收藏

          創業故事-轉

          --轉自

          做共享軟件是有利可圖的,這是真的,1999年3月以前我還不信,可是經過一年多的
          研究和實踐下來,我已經每月能賺4萬多美金了,比某些大公司總裁還多。但是,
          我敢說,80%以上的共享軟件作者并不成功,實際上,他們遠遠沒有賺到他們本來可以
          賺到的收入。

          軟件共享發行銷售(先試后買)是一種市場營銷手段,和其他所有市場營銷手段一樣,
          是有學問的,要想通過軟件共享發行獲得成功,就必須掌握這些學問。

          今天,我來貼上第一篇技術文章,收錢的辦法
          在幾年以前,Internet還沒有流行的時候,共享軟件的作者只能靠從郵件中收到用戶的支票和現金的方法來賺錢,而用戶寄出支票后,還要等上一周或更多的時間得到來自作者的注冊碼。注意,當以下幾種情況發生時,軟件作者的生意就做不成了:
          1)用戶的支票本剛好用完,等他買回新支票本時,消費沖動已經沒有了
          2)用戶的郵票剛好用完,他還不得不去一趟郵局買郵票,轉念一想,這軟件我也不是
          非買不可,算了
          3)用戶無法忍受要等好多天才能拿到注冊碼
          一句話,太不方便了


          現在好了,有了Internet,有了電子商務,用戶可以在最想買你的軟件的一剎那間,迅速的用他的信用卡在網上買下你的軟件,連后悔的時間都沒有,共享軟件發財的日子到來樂。
          那么,如何在網上收取信用卡呢?
          如果你擁有一個公司,在美國銀行有信用卡商號帳戶,又購買了銀行的GATEWAY軟件,在自己的網站上開發了信用卡收費系統當然很好,但對于廣大共享軟件作者來說,這很不現實.有簡單的辦法,就是找一家信用卡收款代理公司,讓他們替你收款,你只要每個月等他們給你寄一張總額的支票(他們會提取一定比例的傭金)就行了.
          這樣的代理公司網站有:
          WWW.QWERKS.COM   提成 15-20% (服務極好,是我的服務商)
          WWW.Shareit.COM
          WWW.REGNOW.COM
          WWW.REGSOFT.COM
          WWW.Kagi.com

          對于咱們國內的共享軟件作者,還要做的一件事就是去中國銀行開個戶頭(北京中行的活期一本通就很好用),如果你打算讓信用卡公司把錢電匯給你,你還要知道銀行的英文名字,地址,帳戶名,
          帳號,轉帳的SWIFT Code(可以從銀行職員那里問到)
          到信用卡代理公司的網站上開戶非常簡單,通常確認它們的一個在線協議,填入一些個人信息和產品信息,幾分鐘就OK了
          這里面有一個值得注意的地方,就是,當用戶付了款后,注冊碼怎么給的問題,你可以選擇由你來給(每收到一份訂單,他們會給你發一封email,包含用戶資料和email),由你生成注冊碼email給用戶,也可以把注冊碼生成代碼給信用卡公司,讓他們編到他們的系統里去,用戶來了訂單后自動發出注冊碼,也可以由你一次性生成幾百個注冊碼給他們,他們每收到一份訂單時用掉一個注冊碼。
          我個人的意見是,這幾個信用卡服務商信譽都非常好,一次給他們幾百個注冊碼是最簡單的辦法,對服務商來說操作簡單,對用戶來說快,交完錢馬上就得到注冊碼了

          當你完成作者和產品在信用卡服務商那里的登記后,就會得到一個URL連接,你把這個連接加到你的主頁上面,標上一個“Buy Now”,用戶點這里就可以用信用卡付款了,當然,你也可以把這個連接做到你的軟件界面里去,這樣用戶在試用你的軟件時,隨時想買都可以點擊這個連接上網購買

          具體實例可以參考我的網站和軟件
          http://www.zy2000.com
          MP3 CD Maker


          對于一些Internet軟件,如斷點續傳的下載軟件,還有另外一種賺錢方法,就是對用戶免費,而在軟件界面上登一個banner廣告賺取廣告費。最有名的廣告代理商是
          www.radiate.com
          他的廣告付費是每CPM 2-5美元,也就是說,如果一天里有10萬個用戶使用了你的軟件一次的話,你就得到200-500美元。這家公司聲稱,著名的下載工具軟件Gozilla!落戶Radiate后,每月從Radiate那里賺到22萬美元,我們著名的NetAnt是不是該趕快行動了?

          我們也不反對用戶用支票和現金購買軟件,事實上,信用卡服務商都提供支票和現金收款業務,我們可以在網頁中提供信用卡服務商的地址和服務熱線電話,具體例子可以參考我的網頁中 FAQ 一頁的內容

          posted @ 2007-04-25 13:50 crazy zerlot 閱讀(290) | 評論 (0)編輯 收藏

          HQL查詢語言基礎

          1 .from

          1.1單表查詢

          from eg.cat as cat.其中,cat只是一個別名,為了用其他子語句的時候書寫簡單

          1.2多表查詢

          from eg.Cat,eg.Dog
          from eg.Cat as cat,eg.Dog as dog
          2 join相關
          (inner) join
          left (outer) join
          right (outer) join
          full join
          HQL同樣對SQL中的這些特性支持
          下面插播一個小話題,關于上邊的那些特性,我一直都沒怎么用,今天既然說到這里,就想
          把上邊的幾個特性的用法說一下,也算對自己的一個補充:
          假設有兩個表:部門、員工,下面列舉一些數據:
          員工(Employee):
          ID Name DepNo
          001 Jplateau 01
          002 Jony 01
          003 Camel 02
          部門(Department):
          ID Name
          01 研發部
          02 營銷部

          在Hibernate中我們操縱的都是對象,所以我們操縱的是部門類和員工類
          1).(inner) join
          select employee.ID as id1,employee.Name as name1,department.ID as id2,department.Name
          as name2 from Employee as employee join Department as department on employee.DepNo=
          department.ID (注意到條件語句我用on 沒有用where)
          那么執行結果是什么呢?
          id1 name1 id2 name2
          ++++++++++++++++++++++++++++++++++++++
          001 Jplateau 01 研發部
          002 Jony 01 研發部

          2).left (outer) join
          select employee.ID as id1,employee.Name as name1,department.ID as id2,department.Name
          as name2 from Employee as employee left join Department as department on employee.DepNo=
          department.ID
          那么執行結果又該是什么呢?
          id1 name1 id2 name2
          ++++++++++++++++++++++++++++++++++++++
          001 Jplateau 01 研發部
          002 Jony 01 研發部
          003 Camel null null
          {就是說此時我要已第一個表的記錄多少為準,第二個表中沒有相應紀錄的時候填充null}
          3). right (outer) join
          select employee.ID as id1,employee.Name as name1,department.ID as id2,department.Name
          as name2 from Employee as employee right join Department as department on employee.DepNo=
          department.ID
          那么執行結果又該是什么呢?
          id1 name1 id2 name2
          ++++++++++++++++++++++++++++++++++++++
          001 Jplateau 01 研發部
          002 Jony 01 研發部
          null null 02 營銷部
          {就是說此時我要已第二個表的記錄多少為準,第一個表中沒有相應紀錄的時候填充null}

          3 大小寫敏感

          4。select語句
          就是要確定你要從查詢中返回哪些對象或者哪些對象的屬性。寫幾個例子吧:
          select employee form Employee as employee
          select employee form Employee as employee where employee.Name like 'J%'
          select employee.Name form Employee as employee where employee.Name like 'J%'
          select employee.ID as id1,employee.Name as name1,department.ID as id2,department.Name
          as name2 from Employee as employee right join Department as department on employee.DepNo=
          department.ID

          select elements(employee.Name) from Employee as employee
          (不明白elements到底是做什么用的?望給于說明)
          等等
          5。數學函數
          JDO目前好像還不支持此類特性。
          avg(...), sum(...), min(...), max(...)

          count(*)

          count(...), count(distinct ...), count(all...)

          其用法和SQL基本相同

          select distinct employee.name from Employee as employee
          select count(distinct employee.name),count(employee) from Employee as employee

          6。polymorphism (暫時不知道如何解釋?)
          from com.test.Animal as animal
          不光得到所有Animal得實例,而且可以得到所有Animal的子類(如果我們定義了一個子類Cat)
          一個比較極端的例子
          from java.lang.Object as o
          可以得到所有持久類的實例

          7。where語句
          定義查詢語句的條件,舉幾個例子吧:
          from Employee as employee where employee.Name='Jplateau'
          from Employee as employee where employee.Name like 'J%'
          from Employee as employee where employee.Name like '%u'
          在where語句中“=”不光可以比較對象的屬性,也可以比較對象,如:
          select animal from com.test.Animal as animal where animal.name=dog

          8。表達式

          在SQL語句中大部分的表達式在HQL中都可以使用:
          mathematical operators +, -, *, /

          binary comparison operators =, >=, <=, <>, !=, like

          logical operations and, or, not

          string concatenation ||

          SQL scalar functions like upper() and lower()

          Parentheses ( ) indicate grouping

          in, between, is null

          JDBC IN parameters ?

          named parameters :name, :start_date, :x1 (這種應該是另一種"?"的變通解決方法)

          SQL literals 'foo', 69, '1970-01-01 10:00:01.0'

          Java public static final constants eg.Color.TABBY

          其他不必解釋了,在這里我只想對查詢中的參數問題說明一下:
          大家知道在SQL中進行傳遞參數進行查詢的時候,我們通常用PreparedStatement,在語句中寫一大堆的“?”,
          在hql中也可以用這種方法,如:
          List mates = sess.find(
          "select employee.name from Employee as employee " +
          "where employee.Name=? ",
          name,
          Hibernate.STRING
          );
          (說明:上面利用Session里的find方法,在hibernate的api Session中重載了很多find方法,它可以滿足你多種形式的查詢)
          上邊是一個參數的情形,這種情況下緊接著引入參數和定義參數的類型,當為多個參數,調用另一個find方法,它的后兩個
          參數都是數組的形式。

          還有另外一種方法來解決上邊的問題,JDO也有這樣的方法,不過和hibernate的表現形式上有差別,但他們兩個骨子里卻是
          一樣的,如:
          Query q = sess.createQuery("select employee.name from Employee as employee where employee.Name=:name");
          q.setString("name", "Jplateau");
          //當有多個參數的時候在此逐一定義
          Iterator employees = q.iterate();

          9。order 語句
          和sql語句沒什么差別,如:
          select employee.name from Employee as employee where employee.Name like 'J%' order by employee.ID desc (或者asc)

          10。group by 語句
          同樣和sql語句沒什么差別,如:

          select employee.name,employee.DepNo from Employee as employee group by employee.DepNo

          select foo.id, avg( elements(foo.names) ), max( indices(foo.names) ) from eg.Foo foo group by foo.id
          {Note: You may use the elements and indices constructs inside a select clause, even on databases with no subselects.}
          誰幫我解釋一下上邊兩句,謝過!

          11。子查詢
          hibernate同樣支持子查詢,寫幾個例子:

          from eg.Cat as fatcat where fatcat.weight > ( select avg(cat.weight) from eg.DomesticCat cat )

          posted @ 2007-04-25 13:21 crazy zerlot 閱讀(320) | 評論 (0)編輯 收藏

          23種設計模式及其對應實例-轉

          -轉載

          下面是作者對設計模式的理解并自以為所對應的實例
          一 : 單例模式(Singleton)
           
          賬本類:1 單一實例 2 給多個對象共享 3 自己創建。網頁計數器
            
          二:策略模式(Strategy) 
           
          使用QQ泡MM時使用外掛  客戶端 :ME 抽象類: 外掛 具體:策略(圖片,笑話,名人名言)
          圖書銷售算法(不同書本折扣的算法)
           
          三:原型模式(Prototype)
           
          復印技術: 1 不是同一個對象 2 屬同類
          短消息(轉發) 1-n個MM
           
          四:門面模式(Façade)
           
          Facade典型應用就是數據庫JDBC的應用和Session的應用
          ME---àMM---à(father,mum,sister,brother)
           
          五:備忘錄模式(Memento)
           
          備份系統時使用
          GHOST

          六 : 命令模式(Command)
           
          MM(客戶端)--àME(請求者)--à命令角色--à(具體命令)-à代理處(接收者)--àMM
          上網 IE 輸入 http地址 發送命令
           
          七: 解釋器(Interpreter)
           
          編譯原理之編譯器
          文言文注釋:一段文言文,將它翻譯成白話文
          八:調停者模式(Mediator)
           
          法院和原告,被告的關系
          九:責任鏈模式(CHAIN OF RESPONSIBLEITY)
           
          喝酒時通過成語接龍決定誰喝酒(馬到成功-功不可沒-沒完沒了)
          十:工廠模式(Factory)
           
          水果園—〉(葡萄園,蘋果園)--〉(葡萄,蘋果)(各自生產)
          十一:抽象工廠模式(Abstract Factory)
           
          女媧造人---〉(陰,陽)--〉(人,獸)----〉(男人,女人,公獸,母獸)(人和獸屬于不同的產品類)
           
          十二:建造模式(Builder)
           
          汽車制造
           
          十三:合成模式(Composite)
           
          windows的目錄樹(文件系統)
           
          十四:裝飾模式(DECORATOR)
           
          在visio中文件可以使用背景進行裝飾
          變廢為寶
          十五:設計模式之Adapter(適配器)
           
          充電器(手機和220V電壓)
          jdbc-odbc橋
          十六:橋梁模式(Bridge)
           
          jdbc驅動程序
           
          十七:代理模式(Proxy)
           
          用代理服務器連接出網
          銷售代理(廠商)律師代理(客戶)
          foxmail
          槍手
           
          十八:享元模式(Flyweight)
           
          字體的26個字母和各自的斜體等
           
          十九:狀態模式(State)
           
          人心情不同時表現不同有不同的行為
          編鐘
          登錄login logout
           
          二十:觀察者模式(Observer)
           
          公司郵件系統everyone@sina.com的應用。當公司員工向這個郵箱發郵件時會發給公司的每一個員工。如果設置了Outlook則會及時收到通知。
          接收到短消息
           
          二十一:模板方法模式(Template)
           
          使用網頁設計時使用的模板架構網頁(骨架) 算法的各個邏輯系統
           
          二十二:訪問者模式(Visitor)
           
          電腦銷售系統: 訪問者(自己)---〉電腦配置系統(主板,CPU,內存。。。。。。)
           
          二十三:迭代子模式(Iterator)
           
          查詢數據庫,返回結果集(map, list, set)
           
          下面的參考文獻是讀書筆記的全部參考文獻。這里不一定用到的。
          參考文獻:
          http://blog.csdn.net/airhand/
          http://blog.csdn.net/bloom121/
          http://blog.csdn.net/laurecn/
          http://blog.csdn.net/legendinfo/
          http://www-128.ibm.com/developerworks/cn/java/l-struts1-1/
          《Design Patterns》
          《Java與模式》
          《設計模式:可復用面向對象軟件的基礎》

           

          Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1227902

          posted @ 2007-04-17 15:15 crazy zerlot 閱讀(1293) | 評論 (0)編輯 收藏

          JavaScript 技巧

               摘要: 事件源對象 event.srcElement.tagName event.srcElement.type 捕獲釋放 event.srcElement.setCapture();  event.srcElement.releaseCapture();  事件按鍵 event.keyCode event.shiftKey event.altKey event....  閱讀全文

          posted @ 2007-04-16 16:46 crazy zerlot 閱讀(429) | 評論 (0)編輯 收藏

          Jive 源碼研究與設計模式-轉

          轉自 IBM 劉武東,謝謝作者的辛勤勞動!

          前言

          Jive是一個開放的Java源代碼項目。其目標是建設一個開放結構的,強壯的,易于擴展的基于JSP的論壇。在其設計目標的指導下,其結構設計得非常得好,融合了很多新的觀念,比如Design Pattern,可更換的Skin,可插入Plug等等。詳細解讀其源代碼對于理解這些新的設計上的概念是很有裨益的。如果你對Design Pattern和Java語言有一定的了解,但是還是會時常迷惑于其中的話,不妨研究研究Jive源代碼,一定會對其中的很多概念有更深入的理解。這篇文章源于我的Jive源代碼研究筆記,希望能夠提綱挈領,帶領大家進入到這個美好的世界。當然,如果沒有時間仔細地看源代碼的話,看看這篇文章,我想也是會有一些幫助的。

          再開始之前,需要指出的是,Jive中對Design Pattern的應用,并沒有拘禮與GOF書中所給出的實現方法,而是有許多變通的地方。一方面,我想是由于具體的實際需要,另一方面,我想這也是設計觀念進化的結果吧。因而,這些變通的地方,將是我講解的重點。


          整體結構概敘

          基于一個OO的設計原則:面向接口編程,而不是針對實現編程。Jive在設計的時候,把其大部分的基本對象都設計為接口或者抽象類。在Jive中,基本的接口有Forum,ForumMessage,ForumThread,Group,User,Authorization和Query。我們可以很容易的從這些接口的名字來知道他們的功用,下面的類圖給出了這些類之間的一些靜態關系:



          圖1:Jive整體關系
          圖1:Jive整體關系

          你可能會有疑問,為什么會都是接口呢?這是基于擴展性考慮的。在Jive給出的實現中,所有的這些接口,Forum,ForumMessage,User等等,都使用數據庫來實現的,一條消息,或者一個用戶對應于數據庫中的一條消息Jive使用了DbForum,DbForumMessage,DbUser等類來實現這些接口,通過JDBC來操作數據庫,使之作為論壇的底層支撐。

          然而,有時候,或許我們并不想使用數據庫,比如我們想只是使用文件系統來作為論壇的底層支撐,這時候,我們需要做的只是編碼實現了Forum等等接口的諸如FileFroum,FileForumMessage等對象,然后嵌入Jive中即可,原有的任何代碼都可以不用改變!!!這就是面向接口編程的威力了!

          下面來看看具體的設計和編碼。

          AbstractFactory模式和可擴展性

          如果要實現較好的可擴展性,AbstractFactory模式確實是一件利器。如上面所說,如果要創建的Forum接口的不同實現,而又不想更改代碼的話,就需要用到抽象工廠了。再Jive中,AuthorizationFactory類是一個抽象類,用來創建Authorization對象。這是一個抽象工廠,可以通過不同的子類來創建不同的Authorization對象。這個工廠的實現方法是:

          在AuthorizationFactory中使用一個private static變量factory,用來引用具體的抽象工廠的實例:
          private static AuthorizationFactory factory = null;

          用一個private static的String,來指明具體的抽象工廠的子類類名:
          private static String className ="com.coolservlets.forum.database.DbAuthorizationFactory";

          然后是用一個private static的loadAuthorizationFactory方法來給這個factory變量賦值,生成具體的抽象工廠類:

             private static void loadAuthorizationFactory() {
                      if (factory == null) {
                      synchronized(className) {
                      if (factory == null) {
                      String classNameProp = PropertyManager.getProperty(
                      "AuthorizationFactory.className"
                      );
                      if (classNameProp != null) {
                      className = classNameProp;
                      }
                      try {
                      Class c = Class.forName(className);
                      factory = (AuthorizationFactory)c.newInstance();
                      }
                      catch (Exception e) {
                      System.err.println("Exception loading class: " + e);
                      e.printStackTrace();
                      }
                      }
                      }
                      }
                      }

          在static的getAuthorization方法返回一個Authorization的過程中,先初始化工廠類factory變量,然后用factory的createAuthorization方法來創建:

             public static Authorization getAuthorization(String username,
                      String password) throws UnauthorizedException
                      {
                      loadAuthorizationFactory();
                      return factory.createAuthorization(username, password);
                      }

          不同的子類有不同的createAuthorization方法的實現。比如在DbAuthorizationFactory這個AuthorizationFactory的數據庫實現子類中,createAuthorization方法是這樣實現的:

             public Authorization createAuthorization(String username, String password)
                      throws UnauthorizedException
                      {
                      if (username == null || password == null) {
                      throw new UnauthorizedException();
                      }
                      password = StringUtils.hash(password);
                      int userID = 0;
                      Connection con = null;
                      PreparedStatement pstmt = null;
                      try {
                      con = DbConnectionManager.getConnection();
                      pstmt = con.prepareStatement(AUTHORIZE);
                      pstmt.setString(1, username);
                      pstmt.setString(2, password);
                      ResultSet rs = pstmt.executeQuery();
                      if (!rs.next()) {
                      throw new UnauthorizedException();
                      }
                      userID = rs.getInt(1);
                      }
                      catch( SQLException sqle ) {
                      System.err.println("Exception in DbAuthorizationFactory:" + sqle);
                      sqle.printStackTrace();
                      throw new UnauthorizedException();
                      }
                      finally {
                      try {  pstmt.close(); }
                      catch (Exception e) { e.printStackTrace(); }
                      try {  con.close();   }
                      catch (Exception e) { e.printStackTrace(); }
                      }
                      return new DbAuthorization(userID);
                      }

          在這個類中,可以看到抽象類和具體的子類之間的關系,它們是如何協作的,又是如何劃分抽象方法和非抽象方法的,這都是值得注意的地方。一般的,抽象方法需要子類來實現,而抽象類中的非抽象方法應該所有子類所能夠共享的,或者可是說,是定義在抽象方法之上的較高層的方法。這確實是一個抽象工廠的好例子!雖然實現的方法已經和GOF中給出的實現相差較遠了,但思想沒變,這兒的實現,也確實是要巧妙的些。

          還有就是靜態方法的使用,使得這個類看起來有些Singleton的意味。這使得對于AbstractFactory的創建變得簡單。

          下面的類圖給出了這個AbstractFactory的實現的總體情況:



          圖2:AbstractFactory模式的實現類圖
          圖2:AbstractFactory模式的實現類圖

          在AuthorizationFactory中定義的其它方法,涉及到具體的如何創建Authorization,都是作為abstract方法出現,具體實現留給子類來完成。

          這樣,在需要生成一個Authorization的時候,只需要調用AuthorizationFactory的靜態方法getAuthorization就可以了,由子類實現了具體的細節。

          其它的,如同上面講到的,在創建Forum的時候用的ForumFactory,具有同上面一樣的實現,這就是模式之所以稱為模式的所在了。





          回頁首


          Proxy模式和權限控制

          Proxy模式的功能有很多,比如遠程代理,用來給遠程對象提供一個本地代表;虛代理,用來為創建開大開銷的對象提供緩沖,等等。在Jive中使用的是保護代理,為被保護的對象提供權限控制。

          我們都知道在一個論壇中,權限的控制是必須的,否則論壇就很可能會被搞得一團糟。Jive中引入Proxy對象,Authorization接口以及權限描敘屬類來提供對論壇的保護。

          以ForumFactory為例,一個額外的ForumFactoryProxy來處理權限認證的工作,它為某一個ForumFactory提供了一個代理,保證只有授權的用戶才能夠存取ForumFactory的某些操作。實際上ForumFactory在這兒不僅僅只是一個生成Forum的類的,它更像是一個Forum的管理類。提供了添加,刪除,枚舉等等一系列的功能,而有些功能不是什么樣的人都可以使用的,因而引入了另外的一個代理類來處理權限的問題。

          當然,代理類需要繼承ForumFactory,以使方法簽名一致: ForumFactoryProxy extends ForumFactory

          在它的構造方法中,就提供了一個ForumFactory對象,這是需要被代理的對象;一個Authorization對象,提供用戶信息;還有一個ForumPermissions,提供認證信息:

             public ForumFactoryProxy(ForumFactory factory, Authorization authorization,
                      ForumPermissions permissions)
                      {
                      this.factory = factory;
                      this.authorization = authorization;
                      this.permissions = permissions;
                      }

          一般的代理過程都是這樣的,在訪問某個方法之前,必須接受權限的檢查,以createForum為例:

             public Forum createForum(String name, String description)
                      throws UnauthorizedException, ForumAlreadyExistsException
                      {
                      if (permissions.get(ForumPermissions.SYSTEM_ADMIN)) {
                      Forum newForum = factory.createForum(name, description);
                      return new ForumProxy(newForum, authorization, permissions);
                      }
                      else {
                      throw new UnauthorizedException();
                      }
                      }

          下面給出這個模式的類圖:



          圖3:Proxy模式的類圖
          圖3:Proxy模式的類圖

          這個模式的實現基本上和GOF中所給出的實現一致。在Jive中,幾乎所有的接口,Forum,ForumMessage,ForumThread等等,都會有一個相應的Proxy對象來進行權限控制。而在創建具體的對象的時候,都是用相應的Proxy對象來代替原有的對象返回的。例如在ForumFactory的getInstance()方法中需要返回一個Forum的時候,Jive是這樣做的:

          public static ForumFactory getInstance(Authorization authorization) {
                      ......
                      ForumFactoryProxy proxy = new ForumFactoryProxy(factory,authorization, factory.getPermissions(authorization));
                      return proxy;
                      }

          因而,所有被創建的對象實際上都是Proxy對象,抽象工廠保證了沒有權限驗證的對象根本不會客戶所得到,它們只會在Proxy的內部扮演角色,而永遠不會被外部對象所存取,這樣,就從根本上保證了論壇的安全。





          回頁首


          Decorator模式和過濾器

          一般的在OO設計中,而外功能的添加是通過繼承來實現的,但是繼承有的時候不夠靈活,而且當功能的組合很多的時候,繼承的子類就會成幾何級數增長,使得類多的難以控制。正是基于這樣的考慮,Decorator模式得以誕生。

          Decorator模式相當于封裝了某個特定的操作,當某個對象需要這個操作的時候,加上這個Decorator即可。并且,多個Decorator還可以組合,以提供更多的功能。

          在Jive中,Decorator模式應用在一些過濾器(Filter)中。Filter提供對ForumMessage對象內容的重新構造。比如,當一個ForumMessage對象流過一個名為FilterCodeHighlight的過濾器后,存在于消息中的所有Java源代碼文本,會被重新構造為具有語法高亮顯示的消息。在比如,當經過了語法高亮修飾的消息再流過一個名為FilterHtml的過濾器后,消息中的HTML片斷會被注釋可以在HTML內部顯示文本,這樣就防止了用戶輸入了HTML控制標簽后,使得頁面顯示不正常的問題。

          Jive中,所有的過濾器繼承于一個抽象類ForumMessageFilter,而ForumMessageFilter又實現了ForumMessage接口。也就是說,每一個過濾器實際上也是一個ForumMessage對象。

          ForumMessageFilter中還封裝一個ForumMessage對象。進行過濾的方法很簡單,使用的是getBody(),比如在FilterCodeHighlight這個類中:

             public String getBody() {
                      return highlightCode(message.getBody());
                      }

          highlightCode是一個private方法,實施具體的過濾的細節。getBody()方法實際上是定義在ForumMessage接口中的,當調用過濾器的getBody()方法時,就能夠得到結構重整后的ForumMessage對象了。這個對象可以被其他客戶引用,也可以在傳遞給另外的過濾器,實施進一步的操作。

          在實現一個具體的消息的過濾的時候,在Forum中有addForumMessageFilter(),applyFilters()方法,用來實現對過濾器的應用。

          對一個Forum,使用addForumMessageFilter()方法添加一個Filter的時候,并沒有指定一個具體的Message,而只是一個規則(Filter中封裝了過濾規則),然后applyFilter()方法中,實施這些規則:

             public ForumMessage applyFilters(ForumMessage message) {
                      //Loop through filters and apply them
                      for (int i=0; i < filters.length; i++) {
                      message = filters[i].clone(message);
                      }
                      return message;
                      }

          過濾器的clone()方法,為過濾器復制消息體。這個方法的使用,分離了在過濾器中對于消息體和過濾規則的初始化過程,這也是一個值得借鑒的技巧!

          下面給出Decorator模式的類圖:



          圖4:Decorator模式的類圖
          圖4:Decorator模式的類圖

          我們可以看到Decorator模式實際上和Proxy模式是很相近的,但是它們代表兩個不同的功能含義。Proxy模式提供一個對象的控制,而Decorator模式則是為對象提供額外的功能。

          Iterator模式和論壇的瀏覽erator模式用來分離數據結構和遍歷算法,降低兩者之間的耦合度,以使得同一個數據結構用不同的算法遍歷時,仍能夠具有相同的接口,另一方面,Iterator模式使得當改換遍歷算法后,不需要更改程序的代碼。

          在Java的JDK中本身就定義有一個Iterator接口,在Iterator接口中僅僅定義了三個方法,hasNext()判斷是否遍歷完最后一個元素,next()方法返回要遍歷的數據結構中一個對象,remove()則刪除當前對象。Jive中使用IteratorProxy抽象類繼承了這一接口。這兒Proxy的含義和上面一樣,也就是說,這個IteratorProxy出了會實現Iterator的遍歷功能外,還會有代理權限控制的功能。

          對于論壇中的基本對象Forum,ForumThread,ForumMessage,Group,User都有相應的遍歷器。比如對應于Forum接口有ForumIteratorProxy對象。這個ForumIteratorProxy遍歷器就相當于一個封裝了一系列Forum對象的集合類,通過定義好的接口hasNext()和next()可以方便的遍歷這個集合,而并不需要知道是如何遍歷這個集合的。遍歷的算法可能很簡單,也可能很復雜,但是對于外部的客戶而言,這并沒有任何的區別。

          而對于論壇中具體的遍歷方法,這取決于具體的實現,在Jive中給出的是數據庫的實現。

          我們就以MessageIteratorProxy為例,來講解Iterator模式的用法。

          DbThreadIterator對象實現了Iterator接口,是對于一個Thread中所有Message的遍歷器,我們來看看它是如何實現的。

          hasNext()判斷在這個Thread中是不是還有下一條Message:

          public boolean hasNext() {
                      if (currentIndex+1 >= messages.length) {
                      return false;
                      }
                      return true;
                      }

          next()方法從數據庫中取出與在這個Thread中的下一條Message:

             public Object next() throws java.util.NoSuchElementException {
                      ForumMessage message = null;
                      if (nextMessage != null) {
                      message = nextMessage;
                      nextMessage = null;
                      }
                      else {
                      message = getNextMessage();
                      if (message == null) {
                      throw new java.util.NoSuchElementException();
                      }
                      }
                      return message;
                      }

          這樣,通過對數據庫的操作,DbThreadIterator實現了對一個Thread中所有Message遍歷的方法。

          再ForumThread接口中有messages()方法,返回在這個Thread中的所有Message的一個遍歷器(Iterator),實際上也就是返回了一個Message的集合:
          public Iterator messages();

          在DbForumThread中實現了這個方法:
          public Iterator messages() {return new DbThreadIterator(this);}

          從DbForumThread的messages()方法中所返回的就是這個Thread中所有Message的一個遍歷器,通過這個遍歷器,我們就可以訪問Thread中的所有的Message了。當然,事情還沒有完,由于權限的問題,我們還需要構造這個遍歷器的Proxy對象,然后通過這個Proxy對象來訪問遍歷器。

          下面的類圖給出了在Jive中Iterator模式的實現方法:



          圖5:Jive中Iterator模式的實現
          圖5:Jive中Iterator模式的實現

          在Jive中,因為在一個Thread之下,Message是按樹形結構組織的,因而,當需要層級表示一個Thread中的Message之間的關系的時候,僅僅用上面講到的線性的Iterator是不夠的。這時候,對Iterator的概念進行推廣,就引入了TreeWalker接口。

          顧名思義,TreeWalker提供了遍歷一個樹和存取樹上節點的方法:

          public interface TreeWalker {
                      public ForumMessage getRoot();
                      public ForumMessage getChild(ForumMessage parent, int index);
                      public int getChildCount(ForumMessage parent);
                      public int getRecursiveChildCount(ForumMessage parent);
                      public int getIndexOfChild(ForumMessage parent, ForumMessage child);
                      public boolean isLeaf(ForumMessage node);

          TreeWalker只是Iterator的簡單推廣,并沒有Iterator應用的那么廣泛,而且,也可以很容易的在TreeWalker上面在套一層Iterator的借口,讓它在某些情況下行使Iterator的職責。這兒就不再多討論了。

          再此,Jive設計中所有涉及到的設計模式的地方,基本上都講完了,看完了之后,是不是對設計模式有了更進一步的了解了呢?

          下一部分的內容,將會涉及到具體的編碼,深入到JSP的內部,我們將會看到Jive中是如何實現可更換的Skin的,還會涉及Tag Library的一些內容。好了,這次就到這兒了。下次再見。

          posted @ 2007-04-14 12:46 crazy zerlot 閱讀(623) | 評論 (0)編輯 收藏

          徹底明白Java的IO系統-轉

          轉載自http://hi.baidu.com/ahunspun/blog/item/0069084e9882a0cbd0c86a66.html

          一. Input和Output
          1. stream代表的是任何有能力產出數據的數據源,或是任何有能力接收數據的接收源。在Java的IO中,所有的stream(包括Input和Out

          stream)都包括兩種類型:

          1.1 以字節為導向的stream
          以字節為導向的stream,表示以字節為單位從stream中讀取或往stream中寫入信息。以字節為導向的stream包括下面幾種類型:
          1) inputstream:
          1) ByteArrayInputStream:把內存中的一個緩沖區作為InputStream使用
          2) StringBufferInputStream:把一個String對象作為InputStream
          3) FileInputStream:把一個文件作為InputStream,實現對文件的讀取操作
          4) PipedInputStream:實現了pipe的概念,主要在線程中使用
          5) SequenceInputStream:把多個InputStream合并為一個InputStream

          2) Outputstream
          1) ByteArrayOutputStream:把信息存入內存中的一個緩沖區中
          2) FileOutputStream:把信息存入文件中
          3) PipedOutputStream:實現了pipe的概念,主要在線程中使用
          4) SequenceOutputStream:把多個OutStream合并為一個OutStream

          1.2 以Unicode字符為導向的stream
          以Unicode字符為導向的stream,表示以Unicode字符為單位從stream中讀取或往stream中寫入信息。以Unicode字符為導向的stream包括下面幾

          種類型:
          1) Input Stream
          1) CharArrayReader:與ByteArrayInputStream對應
          2) StringReader:與StringBufferInputStream對應
          3) FileReader:與FileInputStream對應
          4) PipedReader:與PipedInputStream對應

          2) Out Stream
          1) CharArrayWrite:與ByteArrayOutputStream對應
          2) StringWrite:無與之對應的以字節為導向的stream
          3) FileWrite:與FileOutputStream對應
          4) PipedWrite:與PipedOutputStream對應
          以字符為導向的stream基本上對有與之相對應的以字節為導向的stream。兩個對應類實現的功能相同,字是在操作時的導向不同。如

          CharArrayReader:和ByteArrayInputStream的作用都是把內存中的一個緩沖區作為InputStream使用,所不同的是前者每次從內存中讀取一個

          字節的信息,而后者每次從內存中讀取一個字符。
          1.3 兩種不現導向的stream之間的轉換
          InputStreamReader和OutputStreamReader:把一個以字節為導向的stream轉換成一個以字符為導向的stream。
          2. stream添加屬性
          2.1 “為stream添加屬性”的作用
          運用上面介紹的Java中操作IO的API,我們就可完成我們想完成的任何操作了。但通過FilterInputStream和FilterOutStream的子類,我們可以

          為stream添加屬性。下面以一個例子來說明這種功能的作用。
          如果我們要往一個文件中寫入數據,我們可以這樣操作:
          FileOutStream fs = new FileOutStream(“test.txt”);
          然后就可以通過產生的fs對象調用write()函數來往test.txt文件中寫入數據了。但是,如果我們想實現“先把要寫入文件的數據先緩存到內存

          中,再把緩存中的數據寫入文件中”的功能時,上面的API就沒有一個能滿足我們的需求了。但是通過FilterInputStream和FilterOutStream的

          子類,為FileOutStream添加我們所需要的功能。
          2.2 FilterInputStream的各種類型
          2.2.1 用于封裝以字節為導向的InputStream
          1) DataInputStream:從stream中讀取基本類型(int、char等)數據。
          2) BufferedInputStream:使用緩沖區
          3) LineNumberInputStream:會記錄input stream內的行數,然后可以調用getLineNumber()和setLineNumber(int)
          4) PushbackInputStream:很少用到,一般用于編譯器開發
          2.2.2 用于封裝以字符為導向的InputStream
          1) 沒有與DataInputStream對應的類。除非在要使用readLine()時改用BufferedReader,否則使用DataInputStream
          2) BufferedReader:與BufferedInputStream對應
          3) LineNumberReader:與LineNumberInputStream對應
          4) PushBackReader:與PushbackInputStream對應
          2.3 FilterOutStream的各種類型
          2.2.3 用于封裝以字節為導向的OutputStream
          1) DataIOutStream:往stream中輸出基本類型(int、char等)數據。
          2) BufferedOutStream:使用緩沖區
          3) PrintStream:產生格式化輸出
          2.2.4 用于封裝以字符為導向的OutputStream
          1) BufferedWrite:與對應
          2) PrintWrite:與對應
          3. RandomAccessFile
          1) 可通過RandomAccessFile對象完成對文件的讀寫操作
          2) 在產生一個對象時,可指明要打開的文件的性質:r,只讀;w,只寫;rw可讀寫
          3) 可以直接跳到文件中指定的位置
          4. I/O應用的一個例子
          import java.io.*;
          public class TestIO{
          public static void main(String[] args)
          throws IOException{
          //1.以行為單位從一個文件讀取數據
          BufferedReader in =
          new BufferedReader(
          new FileReader("F:\\nepalon\\TestIO.java"));
          String s, s2 = new String();
          while((s = in.readLine()) != null)
          s2 += s + "\n";
          in.close();

          //1b. 接收鍵盤的輸入
          BufferedReader stdin =
          new BufferedReader(
          new InputStreamReader(System.in));
          System.out.println("Enter a line:");
          System.out.println(stdin.readLine());

          //2. 從一個String對象中讀取數據
          StringReader in2 = new StringReader(s2);
          int c;
          while((c = in2.read()) != -1)
          System.out.println((char)c);
          in2.close();

          //3. 從內存取出格式化輸入
          try{
          DataInputStream in3 =
          new DataInputStream(
          new ByteArrayInputStream(s2.getBytes()));
          while(true)
          System.out.println((char)in3.readByte());
          }
          catch(EOFException e){
          System.out.println("End of stream");
          }

          //4. 輸出到文件
          try{
          BufferedReader in4 =
          new BufferedReader(
          new StringReader(s2));
          PrintWriter out1 =
          new PrintWriter(
          new BufferedWriter(
          new FileWriter("F:\\nepalon\\ TestIO.out")));
          int lineCount = 1;
          while((s = in4.readLine()) != null)
          out1.println(lineCount++ + ":" + s);
          out1.close();
          in4.close();
          }
          catch(EOFException ex){
          System.out.println("End of stream");
          }

          //5. 數據的存儲和恢復
          try{
          DataOutputStream out2 =
          new DataOutputStream(
          new BufferedOutputStream(
          new FileOutputStream("F:\\nepalon\\ Data.txt")));
          out2.writeDouble(3.1415926);
          out2.writeChars("\nThas was pi:writeChars\n");
          out2.writeBytes("Thas was pi:writeByte\n");
          out2.close();
          DataInputStream in5 =
          new DataInputStream(
          new BufferedInputStream(
          new FileInputStream("F:\\nepalon\\ Data.txt")));
          BufferedReader in5br =
          new BufferedReader(
          new InputStreamReader(in5));
          System.out.println(in5.readDouble());
          System.out.println(in5br.readLine());
          System.out.println(in5br.readLine());
          }
          catch(EOFException e){
          System.out.println("End of stream");
          }

          //6. 通過RandomAccessFile操作文件
          RandomAccessFile rf =
          new RandomAccessFile("F:\\nepalon\\ rtest.dat", "rw");
          for(int i=0; i<10; i++)
          rf.writeDouble(i*1.414);
          rf.close();

          rf = new RandomAccessFile("F:\\nepalon\\ rtest.dat", "r");
          for(int i=0; i<10; i++)
          System.out.println("Value " + i + ":" + rf.readDouble());
          rf.close();

          rf = new RandomAccessFile("F:\\nepalon\\ rtest.dat", "rw");
          rf.seek(5*8);
          rf.writeDouble(47.0001);
          rf.close();

          rf = new RandomAccessFile("F:\\nepalon\\ rtest.dat", "r");
          for(int i=0; i<10; i++)
          System.out.println("Value " + i + ":" + rf.readDouble());
          rf.close();
          }
          }
          關于代碼的解釋(以區為單位):
          1區中,當讀取文件時,先把文件內容讀到緩存中,當調用in.readLine()時,再從緩存中以字符的方式讀取數據(以下簡稱“緩存字節讀取方

          式”)。
          1b區中,由于想以緩存字節讀取方式從標準IO(鍵盤)中讀取數據,所以要先把標準IO(System.in)轉換成字符導向的stream,再進行

          BufferedReader封裝。
          2區中,要以字符的形式從一個String對象中讀取數據,所以要產生一個StringReader類型的stream。
          4區中,對String對象s2讀取數據時,先把對象中的數據存入緩存中,再從緩沖中進行讀取;對TestIO.out文件進行操作時,先把格式化后的信

          息輸出到緩存中,再把緩存中的信息輸出到文件中。
          5區中,對Data.txt文件進行輸出時,是先把基本類型的數據輸出屋緩存中,再把緩存中的數據輸出到文件中;對文件進行讀取操作時,先把文

          件中的數據讀取到緩存中,再從緩存中以基本類型的形式進行讀取。注意in5.readDouble()這一行。因為寫入第一個writeDouble(),所以為了

          正確顯示。也要以基本類型的形式進行讀取。
          6區是通過RandomAccessFile類對文件進行操作。

          posted @ 2007-04-13 00:07 crazy zerlot 閱讀(314) | 評論 (0)編輯 收藏

          Java 通用線程池-轉自CSDN

               摘要: 感謝ryang的勞動! Java實現通用線程池 線程池通俗的描述就是預先創建若干空閑線程,等到需要用多線程去處理事務的時候去喚醒某些空閑線程執行處理任務,這樣就省去了頻繁創建線程的時間,因為頻繁創建線程是要耗費大量的CPU資源的。如果一個應用程序需要頻繁地處理大量并發事務,不斷的創建銷毀線程往往會大大地降低系統的效率,這時候線程池就派上用場了。    &...  閱讀全文

          posted @ 2007-04-12 23:33 crazy zerlot 閱讀(476) | 評論 (0)編輯 收藏

          主站蜘蛛池模板: 青州市| 兴化市| 大姚县| 宁海县| 平利县| 和平区| 涞水县| 社旗县| 威信县| 巧家县| 海南省| 彭州市| 禹州市| 东至县| 衢州市| 棋牌| 渭南市| 长岛县| 大厂| 灵宝市| 横山县| 黑龙江省| 汶川县| 丹东市| 济宁市| 柳江县| 牡丹江市| 陆河县| 临高县| 观塘区| 星子县| 章丘市| 肇庆市| 精河县| 格尔木市| 张掖市| 比如县| 江达县| 炎陵县| 武山县| 平乐县|