nighty

          折騰的年華
          posts - 37, comments - 143, trackbacks - 0, articles - 0

          2011年10月13日

          系統(tǒng)為ubuntu server,二臺(tái)機(jī)器A和B,IP為A 192.168.1.111,B 192.168.1.222
          A為rsync server,啟動(dòng)為守護(hù)進(jìn)程,B為備份機(jī),做為rsync client,最后用crontab做一個(gè)簡(jiǎn)單的作業(yè),定時(shí)在B上執(zhí)行同步文件的功能
          A的安裝和配置如下:
          1.  apt-get install rsync   可能提示系統(tǒng)已經(jīng)安裝有了
          2. 配置文件/etc/rsyncd.conf
              默認(rèn)安裝時(shí)是不會(huì)有這個(gè)配置文件的,但是可以 cp /usr/share/doc/rsync/examples/rsyncd.conf /etc  把它示例中的配置文件拷貝過(guò)來(lái)
              vi /etc/rsyncd.conf    這里參數(shù)有點(diǎn)多,但是有些可以先不管,關(guān)注重點(diǎn)的
              [ftp]  這里是模塊,可以配置多個(gè),這個(gè)是系統(tǒng)默認(rèn)給出的一個(gè)配置,下面給一個(gè)本機(jī)上的配置示例:
          --------------------------------------------------------------------------------------------------
          # so omit the "pid file" line completely in that case.
          pid file=/var/run/rsyncd.pid
          #syslog facility=daemon
          #socket options=
          # MODULE OPTIONS
          [share]
          comment = public archive
          path = /var/www/pub
          use chroot = no
          max connections=2
          # lock file = /var/lock/rsyncd
          # the default for read only is yes...
          read only = no
          list = yes
          uid = nobody
          gid = nogroup
          # exclude = 
          # exclude from = 
          # include =
          # include from =
          auth users = rsync
          secrets file = /etc/rsyncd.secrets
          strict modes = yes
          hosts allow = 192.168.1.222
          # hosts deny =
          ignore errors = yes
          ignore nonreadable = yes
          transfer logging = yes
          log format = %t: host %h (%a) %o %f (%l bytes). Total %b bytes.
          timeout = 600
          refuse options = checksum dry-run
          dont compress = *.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz
          ---------------------------------------------------------------------------------------------
          這里,最上面的是pid文件位置。然后配置了一個(gè)模塊名叫做share,最大連接數(shù)是2,read only = no,指定為非只讀(不然同步時(shí)會(huì)有權(quán)限問(wèn)題)
          而后面的auth users = rsync 是指定一個(gè)同步的賬戶(hù)名叫做rsync,這個(gè)賬戶(hù)的認(rèn)證文件是/etc/rsyncd.secrets,當(dāng)然我們要?jiǎng)?chuàng)建這個(gè)文件

          3.  創(chuàng)建 /etc/rsyncd.secrets文件,內(nèi)容為: rsync:123  表示rsync這個(gè)用戶(hù)的密碼是123 然后修改文件的權(quán)限 chmod 600 /etc/rsyncd.secrets

          4.  rsync server做為守護(hù)進(jìn)程
               vi /etc/default/rsync
               可以看到開(kāi)頭處這樣聲明:
          ------------------------------------
          # start rsync in daemon mode from init.d script?
          #  only allowed values are "true", "false", and "inetd"
          #  Use "inetd" if you want to start the rsyncd from inetd,
          #  all this does is prevent the init.d script from printing a message
          #  about not starting rsyncd (you still need to modify inetd's config yourself).
          RSYNC_ENABLE=inetd
          -------------------------------------------
             做為守護(hù)進(jìn)程,可以設(shè)置為true或是xinetd方式來(lái)啟動(dòng)。于是我們安裝inetd   sudo apt-get install xinetd
             安裝好后配置inetd的配置文件  vi /etc/xinetd.d/rsync ,輸入如下內(nèi)容:
          ---------------------------------------------------
          service rsync
          {
              disable = no
              socket_type = stream
              wait = no
              user = root
              server = /usr/bin/rsync
              server_args = --daemon
              log_on_failure += USERID
          }
          -------------------------------------------------------
          然后啟動(dòng)xinetd,/etc/init.d/xinetd restart,A服務(wù)器的rsyncd server就完成了!

          5.  B服務(wù)器由于是client,不需要配置,也不需要安裝xinetd,直接可以通過(guò)命令行執(zhí)行
          rsync --delete -azvv rsync@192.168.1.111::share /var/www/pub/
          這個(gè)命令就可以直接連接到192.168.111的rsync賬戶(hù),它會(huì)提示你輸入密碼,就是A中的secrets文件中的密碼,然后同步share模塊到本機(jī)的/var/www/pub目錄,你可以事前在A機(jī)器上創(chuàng)建一個(gè)文件如test.txt,隨便寫(xiě)點(diǎn)內(nèi)容,然后執(zhí)行些命令,看是不是B上多了這樣一個(gè)文件?如果是,則表示已經(jīng)連接成功。你接下來(lái)就可以做crontab了!

          posted @ 2013-04-12 12:23 寒武紀(jì) 閱讀(1348) | 評(píng)論 (0)編輯 收藏

          二臺(tái)服務(wù)器,A的內(nèi)網(wǎng)IP為192.168.1.111,B的內(nèi)網(wǎng)IP為192.168.1.222,A做為master,B做為Slave
          1.  配置A的Mysql
               (1)  vim /etc/mysql/my.cnf
                     去掉[mysqld]段中 server_id =1 和log_bin=/var/log/mysql/mysql-bin.log的#注釋
                     加上  binlog-do-db = s3     s3就是要同步的數(shù)據(jù)庫(kù)的名稱(chēng),如果沒(méi)有這一行,表示同步所有的數(shù)據(jù),另外 binlog_ignore_db = mysql。要表示忽略同步的數(shù)據(jù)庫(kù)名稱(chēng)為mysql,如果有多個(gè)要指定同步或是忽略同步的數(shù)據(jù),就配置多行,保存退出。
               (2) 創(chuàng)建一個(gè)復(fù)制用的賬戶(hù)(名稱(chēng)為repl,允許從遠(yuǎn)程連接,密碼為123456):
                    GRANT REPLICATION SLAVE, RELOAD,SUPER, NO *.* TO repl@'%' IDENTIFIED BY '123456';
                  FLUSH PRIVILEGES;
               (3) 重啟mysql服務(wù),或是直接reboot機(jī)器也可以
               (4) 進(jìn)入mysql,然后用 show master status\G  查看二進(jìn)制日志的狀態(tài),看到類(lèi)似以下的結(jié)果:
                    +------------------+----------+--------------+------------------+
                    | File                      | Position  | Binlog_Do_DB | Binlog_Ignore_DB |
                    +------------------+----------+--------------+------------------+
                    | mysql-bin.000003 |     1376  | s3                  |                           |
                    +------------------+----------+--------------+------------------+
          2.  配置B的Mysql
                (1) vim /etc/mysql/my.cnf
                     去掉[mysqld]段中 server_id =1 和log_bin=/var/log/mysql/mysql-bin.log的#注釋?zhuān)裺erver_id改為2,要和master機(jī)器的不一樣。并增加以下內(nèi)容:
                     binlog_do_db=s3
                     log-slave-updates
                    保存退出
               (2) 重啟mysql服務(wù)
               (3) 進(jìn)入mysql,執(zhí)行
                    CHANGE MASTER TO MASTER_HOST='192.168.1.111', MASTER_USER='repl',Master_Port=3306,MASTER_PASSWORD='123456',MASTER_LOG_FILE='mysql-bin.000003',MASTER_LOG_POS=1376;
                    SLAVE START;
                    注意上面的CHANGE語(yǔ)句中,MASTER_LOG_FILE和MASTER_LOG_POS就是上面1.4中提到的show master status命令得到的結(jié)果,指定二進(jìn)制文件的名稱(chēng)和開(kāi)始同步的位置。
               (4) 查看SLAVE狀態(tài):    show slave status\G
          *************************** 1. row ***************************
                         Slave_IO_State: Waiting for master to send event
                            Master_Host: 192.168.1.111
                            Master_User: repl
                            Master_Port: 3306
                          Connect_Retry: 60
                        Master_Log_File: mysql-bin.000003
                    Read_Master_Log_Pos: 1376
                         Relay_Log_File: mysqld-relay-bin.000002
                          Relay_Log_Pos: 1355
                  Relay_Master_Log_File: mysql-bin.000003
                       Slave_IO_Running: Yes
                      Slave_SQL_Running: Yes
                        Replicate_Do_DB: 
                    Replicate_Ignore_DB: 
                     Replicate_Do_Table: 
                 Replicate_Ignore_Table: 
                Replicate_Wild_Do_Table: 
            Replicate_Wild_Ignore_Table: 
                             Last_Errno: 0
                             Last_Error: 
                           Skip_Counter: 0
                    Exec_Master_Log_Pos: 1376
                        Relay_Log_Space: 1512
                        Until_Condition: None
                         Until_Log_File: 
                          Until_Log_Pos: 0
                     Master_SSL_Allowed: No
                     Master_SSL_CA_File: 
                     Master_SSL_CA_Path: 
                        Master_SSL_Cert: 
                      Master_SSL_Cipher: 
                         Master_SSL_Key: 
                  Seconds_Behind_Master: 0
          Master_SSL_Verify_Server_Cert: No
                          Last_IO_Errno: 0
                          Last_IO_Error: 
                         Last_SQL_Errno: 0
                         Last_SQL_Error: 
            Replicate_Ignore_Server_Ids: 
                       Master_Server_Id: 1
              上面的紅色二行如果為YES則表示已經(jīng)正常連接,可以進(jìn)行復(fù)制了。

          posted @ 2013-04-09 20:33 寒武紀(jì) 閱讀(1737) | 評(píng)論 (0)編輯 收藏

              許久沒(méi)用服務(wù)器上裝的那個(gè)postgresql,其實(shí)是用來(lái)做redmine的數(shù)據(jù)庫(kù)的,考慮到mysql可能經(jīng)常升級(jí),而rails的連接組件在安裝上有點(diǎn)麻煩,所以當(dāng)初就裝成postgresql。
              今天準(zhǔn)備備份一下,用的phppgadmin,剛開(kāi)始是提示其中的pg_dump執(zhí)行路徑?jīng)]有配置,重新配置好后,導(dǎo)出的結(jié)果卻是空的損壞文件。于是想算了,還是轉(zhuǎn)到pg的安裝目錄下執(zhí)行pg_dump.
              服務(wù)器裝的是centos 6.2,忘了當(dāng)初是建了一個(gè)用戶(hù)postgres.postgres進(jìn)行安裝的,用其它用戶(hù)切換到pg的安裝目錄下bin/pg_dump是執(zhí)行不了的,提示在指定目標(biāo)下生成導(dǎo)出文件。故猜測(cè)應(yīng)該是postgres這個(gè)用戶(hù)的權(quán)限不足!
              cat /etc/passwd查看一下當(dāng)前有多少用戶(hù),的確有postgres.postgres用戶(hù),密碼多少?忘了!反正有root,直接passwd修改成新的密碼吧,于是就立馬修改了該用戶(hù)的密碼,可以正確切換到postgres用戶(hù)了,還需要root為postgres指定一個(gè)目錄有操作權(quán)限
              chown -R postgres.postgres /var/xxxx   
              然后再回到pg的bin目錄下,執(zhí)行pg_dump redmine > /var/xxx/redmine.bak
              這下終于正常了,別忘了還得去redmine安裝目錄下,備份下files文件夾。
              
              僅以此為筆記,以后可以查閱使用

          posted @ 2013-03-27 22:39 寒武紀(jì) 閱讀(1402) | 評(píng)論 (0)編輯 收藏

                用Flex做企業(yè)應(yīng)用將近有一年時(shí)間了,這個(gè)過(guò)程很累,在國(guó)內(nèi)這方面的積累不多,真正有參考意義的資料的確非常少。經(jīng)過(guò)一段長(zhǎng)時(shí)間的摸索后,多少也積累了一點(diǎn)經(jīng)驗(yàn),就最近的關(guān)于單元測(cè)試的想法做一點(diǎn)總結(jié),由于涉及的知識(shí)較多,這里也只是給出個(gè)人的一種思路。
               眾所周知,F(xiàn)lex的缺點(diǎn)是開(kāi)發(fā)調(diào)試效率較低,而且它只是表現(xiàn)層的一種解決方案。在企業(yè)應(yīng)用中最需要解決的是編譯生成的swf體積問(wèn)題,我想任何客戶(hù)都很難接受一個(gè)企業(yè)應(yīng)用全部打包在一個(gè)swf里,幾MB甚至幾十MB的初始化過(guò)程誰(shuí)都無(wú)法接受,所以都必不可少地采用Module的加載方式,把不同的業(yè)務(wù)功能編譯成獨(dú)立的swf,需要用的時(shí)候再去加載。把核心功能、通信機(jī)制、公共組件設(shè)計(jì)成庫(kù)項(xiàng)目,編譯成swc做為RSL讓業(yè)務(wù)模塊共享調(diào)用,達(dá)到盡量減少業(yè)務(wù)模塊編譯體積的目的。在這方面如果用心優(yōu)化的話,基本上可以控制到每個(gè)swf體積大概在200KB以?xún)?nèi),這樣就算是互聯(lián)網(wǎng)方式部署,客戶(hù)訪問(wèn)仍是可以接受的。
              

               該結(jié)構(gòu)圖給出了一種整體的設(shè)計(jì)方案,F(xiàn)lex的啟動(dòng)肯定得有Application,這個(gè)是用戶(hù)初登錄后第一個(gè)加載的swf(登錄就不要用flex了,用jsp或是模板實(shí)現(xiàn)吧)。所以它負(fù)責(zé)加載你設(shè)計(jì)的整個(gè)框架,包含模塊加載機(jī)制、通信代理方式、基礎(chǔ)庫(kù)初始化等等,而和Java端的通信目前比較有效的仍然是blazeds,這個(gè)技術(shù)需要的介紹內(nèi)容不在本文的范圍之內(nèi)。關(guān)于通信接口的實(shí)現(xiàn)有一種非常有用的方式就是借用Java的動(dòng)態(tài)代理理念,Spring有一個(gè)flex的擴(kuò)展子項(xiàng)目叫做springactionscript,而這個(gè)項(xiàng)目又引用了as3commons的庫(kù)(類(lèi)似于apache commons的一些公共組件)。為什么提及這個(gè),因?yàn)閒lex本身的反射功能api非常難用,所以as3commons就做了擴(kuò)展,它大大簡(jiǎn)化了反射的使用,而且提供了一個(gè)bytecode的工具用于操作字節(jié)碼,它是實(shí)現(xiàn)動(dòng)態(tài)代理的關(guān)鍵。至于為什么要?jiǎng)討B(tài)代理?目的就是達(dá)到在寫(xiě)和Java對(duì)接的接口時(shí),可以只聲明接口,不需要實(shí)現(xiàn)類(lèi)(得減少多少重復(fù)代碼呀?),而和Java對(duì)接接口我們又可以開(kāi)發(fā)一個(gè)工具讓java code 自動(dòng)轉(zhuǎn)成 as code,如果懂得Eclipse插件開(kāi)發(fā)的話還可以進(jìn)一步做一個(gè)插件,達(dá)到Java只寫(xiě)一次就可以自動(dòng)生成對(duì)應(yīng)的flex接口,提高開(kāi)發(fā)效率。
               轉(zhuǎn)入正題,關(guān)于單元測(cè)試的概念,F(xiàn)lash Builder在4.5已經(jīng)把flex unit作為內(nèi)置庫(kù)了,這點(diǎn)和Eclipse把junit內(nèi)置類(lèi)似,而flex unit的使用網(wǎng)上有大量的資料介紹,這里也不多說(shuō)。flex unit在測(cè)試as代碼還是不錯(cuò)的,和junit測(cè)試一樣,提供了一些簡(jiǎn)單的Assert斷言,但是你最痛苦的卻不是as的測(cè)試。企業(yè)開(kāi)發(fā)的特點(diǎn)就是數(shù)據(jù)量不大,但是需求坑爹,經(jīng)常變來(lái)變?nèi)ィ医Y(jié)構(gòu)復(fù)雜,往往一張表很多字段,關(guān)聯(lián)子表,層級(jí)屬性多。而你如果選擇了Flex做了展示層的技術(shù),那必定是看中它比HTML + CSS + JS更強(qiáng)的界面交互功能。的確,這點(diǎn)不容質(zhì)疑,F(xiàn)lex Spark的皮膚機(jī)制的確提供了很多優(yōu)秀的特點(diǎn),不過(guò)如果你想純熟掌握它的整個(gè)機(jī)制,恐怕得花很多時(shí)間閱讀源代碼才行,而皮膚的制作整對(duì)別想讓美工獨(dú)自實(shí)現(xiàn),它同樣是需要技術(shù)積累的,介紹它需要用幾個(gè)篇幅才足夠。任何技術(shù)方案都一樣,BS、CS、AIR在實(shí)現(xiàn)復(fù)雜界面時(shí),對(duì)于開(kāi)發(fā)人員來(lái)說(shuō),最痛苦的莫過(guò)于界面的單元測(cè)試。
               痛苦在哪里?回看上面那幅架構(gòu)圖,業(yè)務(wù)功能界面實(shí)現(xiàn)在Flex,業(yè)務(wù)邏輯在后臺(tái)Java,那么當(dāng)二個(gè)團(tuán)隊(duì)同時(shí)進(jìn)行工作的時(shí)候,溝通就是最大的成本。解決溝通的問(wèn)題就必須在先前設(shè)計(jì)時(shí)約定好接口和數(shù)據(jù)結(jié)構(gòu),那是會(huì)影響雙方團(tuán)隊(duì)協(xié)調(diào)的關(guān)鍵因素。當(dāng)雙方同時(shí)進(jìn)行開(kāi)發(fā)的時(shí)候,勢(shì)必存在前臺(tái)依賴(lài)后臺(tái)的情況,因?yàn)樗艿竭_(dá)界面的前提得在整個(gè)框架載入后(并且可以初始化一堆數(shù)據(jù),發(fā)生了通信),Java后臺(tái)還好說(shuō),依賴(lài)于spring和junit可以做到很好的單元測(cè)試。而flex就痛苦了,我沒(méi)有通訊啥都做不了呀!
               如何設(shè)計(jì)單元測(cè)試?最大的出發(fā)點(diǎn)就是如何切掉和后臺(tái)通信連接,看下面的簡(jiǎn)單結(jié)構(gòu)圖

               實(shí)現(xiàn)思路介紹:
               1.  簡(jiǎn)化Application加載過(guò)程   --   可以套用你主程序中的加載過(guò)程,但是不需要你的主界面其它多余的元素,達(dá)到減少到達(dá)測(cè)試界面的多余步驟(盡可能少地減少鼠標(biāo)和鍵盤(pán)操作)
               2.  定義測(cè)試配置   --   測(cè)試哪個(gè)模塊?哪個(gè)工作流程?你得通過(guò)配置的方式來(lái)定義,而不是每次都手寫(xiě)代碼,才能方便你的成員使用你這個(gè)工具
               3.  模擬后臺(tái)接口實(shí)現(xiàn)  --  記得上面說(shuō)的動(dòng)態(tài)代理嗎?其實(shí)是為接口動(dòng)態(tài)生成一個(gè)實(shí)現(xiàn)類(lèi),然后注入真正通信的實(shí)現(xiàn)代碼,例如WebService、HTTP,既然可以注入這些通信渠道,當(dāng)然就可以注入本地實(shí)現(xiàn)類(lèi)啦
               4.  對(duì)象查看器    --   這個(gè)是神馬?因?yàn)槟愣疾灰狫ava后臺(tái)了,每次操作一個(gè)界面后得提交數(shù)據(jù)吧?沒(méi)有后臺(tái)了,提交到哪里?你得必須把你的提交對(duì)象用界面展示出來(lái)吧?好吧,這個(gè)可是個(gè)難點(diǎn)!

               我想這四個(gè)方面的原則無(wú)非就是:減少單元測(cè)試需要進(jìn)行的步驟(最快到達(dá)測(cè)試界面),脫離后臺(tái)依賴(lài)(自己簡(jiǎn)單模擬后臺(tái)實(shí)現(xiàn),可惜flex沒(méi)有類(lèi)似java的mock庫(kù),悲?。。?,如何查看提交到后臺(tái)的結(jié)果。 單元測(cè)試的目標(biāo):界面能正常加載、提交數(shù)據(jù)正常,如果二者都沒(méi)問(wèn)題,那么聯(lián)調(diào)的時(shí)候就可以非常容易定位到是Flex的問(wèn)題還是Java的問(wèn)題!達(dá)到介分責(zé)任的目標(biāo),當(dāng)然,如果你所在團(tuán)隊(duì)是按模塊分的,也就是說(shuō)flex和java都是同一個(gè)人做,那么就不存在責(zé)任問(wèn)題。

               怎么實(shí)現(xiàn)上面的四個(gè)步驟呢?簡(jiǎn)要地介紹一下吧。
               第1簡(jiǎn)化application加載,其實(shí)你可以把第一張圖中的application加載機(jī)制拷貝過(guò)來(lái),只是主界面可以做得非常簡(jiǎn)單,比如不需要多余的控件(比如過(guò)長(zhǎng)的菜單、當(dāng)前登錄人、時(shí)間、一陀設(shè)置按鈕等),只留下最核心的能到達(dá)你測(cè)試界面的入口,至于怎么設(shè)計(jì)這個(gè)簡(jiǎn)化版的application,那得發(fā)揮你本人的創(chuàng)造力,另外還得看具體的業(yè)務(wù)。

              第2定義測(cè)試配置。模塊如何加載?通信接口本地模擬實(shí)現(xiàn)類(lèi)定義?通過(guò)配置顯示在appliation做為觸發(fā)控件,這些你都得自定義一套xml之類(lèi)的文件來(lái)配置吧,這個(gè)就需要技巧了,不能設(shè)計(jì)得太復(fù)雜,因?yàn)槟愕拈_(kāi)發(fā)人員需要沿用你定義的規(guī)范來(lái)定義它需要測(cè)試的模塊,關(guān)于這方面的知識(shí),可以參考spring加載配置文件方式、struts2加載定義文件等理念,有一個(gè)概念我比較推薦,就是struts2中的include配置文件,允許配置文件分散,讓大家提供代碼和文件時(shí)減少?zèng)_突,又可以套用你正常的加載機(jī)制。

              第3模擬后臺(tái)接口實(shí)現(xiàn)。這個(gè)是比較煩的,模擬機(jī)制本身通過(guò)動(dòng)態(tài)代理倒是不難實(shí)現(xiàn),惡心的是你得自己動(dòng)手用flex簡(jiǎn)單實(shí)現(xiàn)一次后臺(tái)生成數(shù)據(jù)、處理數(shù)據(jù)的邏輯。這里我有個(gè)實(shí)踐的總結(jié)經(jīng)驗(yàn)分享,在前期你調(diào)試完的后臺(tái)接口證明是沒(méi)有問(wèn)題的,那么可以混合使用,一部分調(diào)試過(guò)的接口可以直接用后臺(tái),而新接口才本地模擬。一個(gè)原則就是后臺(tái)有的,已經(jīng)證明穩(wěn)定的就用后臺(tái),沒(méi)有的或是后臺(tái)還沒(méi)有完成的你就自己模擬。

              第4對(duì)象查看器。想想flex不能操作數(shù)據(jù)庫(kù)、由于安全限制不允許直接操作文件、無(wú)法讀取本地文件目錄。而你的測(cè)試數(shù)據(jù)也許會(huì)有關(guān)聯(lián)(特別是在工作流方面),所以你得想一個(gè)方案來(lái)保存你的對(duì)象結(jié)果,而且得以一種人性化的方式查看對(duì)象內(nèi)容。且拋開(kāi)數(shù)據(jù)存儲(chǔ)的問(wèn)題,這個(gè)對(duì)象查看器如何設(shè)計(jì)就夠你頭疼的了,首先是對(duì)象得定義成一種格式,一種人可以看得懂的格式,比如xml,可以支持序列化和反序列化,你得去掉多余的無(wú)用屬性和訪問(wèn)器。又得回到反射機(jī)制上了,序列化其實(shí)不難,難的是反序列化時(shí)如何正確地轉(zhuǎn)成原來(lái)的對(duì)象。列一種本人設(shè)計(jì)的結(jié)構(gòu):
               <xxx   type="com.xx.oo.XXClass">
                    <aa type="String">aaa</aa>
                    <bb type="Boolean">true</bb>
                    <list type="mx.collection.ArrayCollenction">
                        ....
                    </list>
               </xxx>
               對(duì)象分簡(jiǎn)單對(duì)象、復(fù)雜對(duì)象、動(dòng)態(tài)對(duì)象等,如何表達(dá)這種結(jié)構(gòu)和保證序列化時(shí)不丟失數(shù)據(jù)需要細(xì)心考慮。那么最后如何實(shí)現(xiàn)查看器呢?其實(shí)有一個(gè)參考的范例,就是Eclipse的“大綱”視圖,經(jīng)過(guò)實(shí)踐的擴(kuò)展,把樹(shù)視圖換成表格樹(shù)(這種控件原生沒(méi)有,有第三方的可以拿來(lái)修改),看個(gè)樣圖吧!
           
               因?yàn)槟汴P(guān)注的對(duì)象內(nèi)容無(wú)法就是這三個(gè)方面,屬性名、值、和類(lèi)型,又支持以樹(shù)方式導(dǎo)航對(duì)象,已經(jīng)足夠你人眼分辯內(nèi)容了。至于如何有效的保存測(cè)試數(shù)據(jù),并且組織好結(jié)構(gòu),這個(gè)方面我目前也仍在思考中,未有較好的思路。
               以上內(nèi)容僅是出于本人的一種方案,也許有更好的實(shí)現(xiàn)方案,只是水平不足以超過(guò)這種認(rèn)識(shí),希望后續(xù)能進(jìn)一步思考能實(shí)現(xiàn)更加完美的單元測(cè)試框架。
               ST測(cè)試更關(guān)注的界面的自動(dòng)化測(cè)試,這方面涉及的知識(shí)更多,一般公司是很難有財(cái)力和技術(shù)去支持做自動(dòng)化測(cè)試,屬于比較高端的范圍,實(shí)現(xiàn)是很多回歸都靠測(cè)試團(tuán)隊(duì)人肉在實(shí)現(xiàn)。

          posted @ 2012-04-28 12:03 寒武紀(jì) 閱讀(1542) | 評(píng)論 (1)編輯 收藏

                采用Spark進(jìn)行Flex的Web應(yīng)用開(kāi)發(fā)的時(shí)候,往往會(huì)用一個(gè)固定欄,比如說(shuō)類(lèi)似Windows的任務(wù)欄,我們想把它固定在頂部或是底部,用于某些場(chǎng)景存放一些控件。<s:Application>組件中有一個(gè)<s:controlBarContent>屬性和<s:controlBarLayout>,用于設(shè)置Application的一個(gè)組件區(qū)域(我猜官方起的這個(gè)名稱(chēng)大概用意在于此吧),下面這段話就是官方的中文注釋?zhuān)?br />
          Title包含在 Application 容器控件欄區(qū)域中的組件集。Application 容器控件欄區(qū)域的位置和外觀由 spark.skins.spark.ApplicationSkin 類(lèi)確定。默認(rèn)情況下,ApplicationSkin 類(lèi)定義以灰色背景顯示在 Application 容器內(nèi)容區(qū)域頂部的控件欄區(qū)域。創(chuàng)建自定義外觀以更改控件欄的默認(rèn)外觀。
                于是可以簡(jiǎn)單的給<s:controlBarContent>區(qū)域添加各種控件,以及設(shè)置它內(nèi)在的布局(controlBarLayout)。但是,發(fā)現(xiàn)它只能顯示在Application的頂部!
                這是怎么回事,根據(jù)上面的注釋?zhuān)杏X(jué)應(yīng)該原因在它的皮膚,得跟進(jìn)代碼,看一下究竟。
                首先找到<s:Application>控件的標(biāo)準(zhǔn)Skin,可以在Flash Builder中直接查看。
                
                雙擊打開(kāi)ApplicationSkin,里面的代碼包含了各種SVG圖形學(xué)的實(shí)現(xiàn)api調(diào)用,flex管這些庫(kù)叫FVG,大意就是SVG的Flex實(shí)現(xiàn)版本,該庫(kù)實(shí)現(xiàn)得還算簡(jiǎn)潔!
                Application標(biāo)準(zhǔn)皮膚的就是先畫(huà)一個(gè)矩形,然后用一個(gè)Group來(lái)包含不同的形狀,最后一段<s:Group id="contentGroup" width="100%" height="100%" minWidth="0" minHeight="0" />,代表Application的內(nèi)容區(qū)域,F(xiàn)lex從設(shè)計(jì)上區(qū)分了控件樹(shù)和布局樹(shù),有些復(fù)雜,可以參考官方的文檔。因?yàn)锳pplication是屬于容器,所以必須在皮膚中包含這一句,不然程序運(yùn)行時(shí)就看不到它包含的子控件。
               而前面長(zhǎng)長(zhǎng)一串<s:Group id="topGroup">中是畫(huà)了頂欄的外觀,它用FVG庫(kù)畫(huà)了四層:
               <!-- layer 0: control bar highlight -->     底部高亮線(用畫(huà)筆填充一個(gè)矩形)
               <!-- layer 1: control bar fill -->              背景填充線性漸變顏色
               <!-- layer 2: control bar divider line -->  分割線
               <!-- layer 3: control bar -->                  controlBar的具體內(nèi)容容器
               當(dāng)然這個(gè)controlBar不是自己會(huì)出現(xiàn)的,只有當(dāng)你填充了內(nèi)容控件的時(shí)候它才顯示,所以有includeIn="normalWithControlBar, disabledWithControlBar",表示在這二個(gè)State下才顯示,什么時(shí)候State才包含這二個(gè)呢?當(dāng)然,就得去看Application.as的實(shí)現(xiàn)原理,具體篇幅就不描述。
               那么回到最初的問(wèn)題:我想改變controlBar的位置在下方怎么處理?
               從上面的分析可知其實(shí)controlBar的擺放位置是在Skin中定義的,而它是什么布局,它顯示不顯示是通過(guò)Application.as本身的代碼控制的,那么我們就只要自定義Application.as的皮膚就可以,新建一個(gè)外觀mxml,直接復(fù)制官方的ApplicationSkin.mxml的代碼,然后,把<s:Group id="contentGroup" width="100%" height="100%" minWidth="0" minHeight="0" />代碼移到<s:Group id="topGroup">代碼的上面,在你的Application中強(qiáng)制指定skinClass為你自定義的ApplicationSkin,或是通過(guò)css設(shè)定即可。
               再擴(kuò)展思維一下,其實(shí)我們完全可以把controlBar放到左邊或是右邊,甚至任何位置,都取決你在Skin的定義和Application.as的邏輯控制(你可以繼承Application擴(kuò)展)。
               那么controlBar有什么作用?其實(shí)spark的Panel從及它的子類(lèi)TitleWindow都有controlBar的概念,它能獨(dú)立于你容器外的區(qū)域,對(duì)于你容器本身包含的組件和布局不會(huì)產(chǎn)生干擾,以及你設(shè)置了width、height為100%時(shí)也不產(chǎn)生影響。如果你不要controlBar,直接在Application中用布局添加一個(gè)Group也是可以實(shí)現(xiàn),但是它從根本上是屬于布局樹(shù)中contentGroup的內(nèi)容,會(huì)受限于布局。
               Spark Skin的設(shè)計(jì)的確有高明的地方,對(duì)比Flex3的外觀,它提供給設(shè)計(jì)人員的空間實(shí)在大得多,你可以組合圖片和FVG庫(kù)的功能自定義各種外觀,當(dāng)然,我就建議你多熟悉一下FVG庫(kù)的應(yīng)用,畢竟從外加載圖片對(duì)flex來(lái)說(shuō)是一個(gè)消耗,你的程序也會(huì)增肥。

          posted @ 2011-10-13 18:14 寒武紀(jì) 閱讀(2482) | 評(píng)論 (0)編輯 收藏

          主站蜘蛛池模板: 鄂尔多斯市| 九寨沟县| 潼关县| 南投市| 常德市| 紫阳县| 龙陵县| 密云县| 宁海县| 大连市| 平顶山市| 孝义市| 仙游县| 广丰县| 浦江县| 张家口市| 白银市| 吴忠市| 紫金县| 拜泉县| 兴安县| 永修县| 色达县| 禹城市| 谢通门县| 武夷山市| 泸水县| 黔南| 武强县| 当阳市| 泾阳县| 滦平县| 漯河市| 板桥市| 中西区| 清徐县| 务川| 宣汉县| 金门县| 遂昌县| 内丘县|