第一章 規範篇
1. 命名規範
- 類名使用 UpperCamelCase 風格,必須遵從駝峯形式,但以下情形例外:(領域模型 的相關命名)DO / BO / DTO / VO 等。
- 方法名、參數名、成員變量、局部變量都統一使用 lowerCamelCase 風格,必須遵從 駝峯形式。
- 常量命名全部大寫,單詞間用下劃線隔開,力求語義表達完整清楚,不要嫌名字長。
- 抽象類命名使用 Abstract 或 Base 開頭;異常類命名使用 Exception 結尾;測試類 命名以它要測試的類的名稱開始,以 Test 結尾。
- 包名統一使用小寫,點分隔符之間有且僅有一個自然語義的英語單詞。包名統一使用 單數形式,但是類名如果有複數含義,類名可以使用複數形式。 產品模塊對外的接口定義放在nc.itf.模塊名.xx,
服務的實現類nc.impl.模塊名.xx,後臺業務類代碼nc.bs.xx,值對象命名:nc.vo.模塊名,
UI層命名:nc.ui.模塊名。 - 杜絕完全不規範的縮寫,避免望文不知義。
- 如果使用到了設計模式,建議在類名中體現出具體模式。
- 接口類中的方法和屬性不要加任何修飾符號(public 也不要加),保持代碼的簡潔 性,並加上有效的 Javadoc 註釋。儘量不要在接口裏定義變量,如果一定要定義變量,肯定是 與接口方法相關,並且是整個應用的基礎常量。接口類中的方法和屬性不要加任何修飾符號(public 也不要加),保持代碼的簡潔 性,並加上有效的 Javadoc 註釋。儘量不要在接口裏定義變量,如果一定要定義變量,肯定是 與接口方法相關,並且是整個應用的基礎常量。
- 對於 Service 和 DAO 類,基於 SOA 的理念,暴露出來的服務一定是接口,內部 的實現類用 Impl 的後綴與接口區別。
- 如果是形容能力的接口名稱,取對應的形容詞做接口名(通常是–able 的形式)。
- 枚舉類名建議帶上 Enum 後綴,枚舉成員名稱需要全大寫,單詞間用下劃線隔開。
2. 常量定義
- 不允許出現任何魔法值(即未經定義的常量)直接出現在代碼中。
- 所有的字符都必須大寫。採用有意義的單詞組合表達,單詞與單詞之間以“_”下劃線隔開。
- 命名儘量簡短,不要超過16個字符。
- long 或者 Long 初始賦值時,必須使用大寫的 L,不能是小寫的 l,小寫容易跟數字 1 混淆,造成誤解。
- 不要使用一個常量類維護所有常量,應該按常量功能進行歸類,分開維護。如:緩存 相關的常量放在類:CacheConsts 下;系統配置相關的常量放在類:ConfigConsts 下。
- 常量的複用層次有五層:跨應用共享常量、應用內共享常量、子工程內共享常量、包 內共享常量、類內共享常量。
3. OOP規範
- 避免通過一個類的對象引用訪問此類的靜態變量或靜態方法,無謂增加編譯器解析成 本,直接用類名來訪問即可。
- 所有的覆寫方法,必須加@Override 註解。加@Override 可以準確判斷是否覆蓋成功。另外,如果在抽象類中對方法簽名進行修改,其實現類會馬上編 譯報錯。
- 相同參數類型,相同業務含義,纔可以使用 Java 的可變參數,避免使用 Object。 說明:可變參數必須放置在參數列表的最後。(提倡同學們儘量不用可變參數編程) 正例:public User getUsers(String type, Integer… ids)
- Object 的 equals 方法容易拋空指針異常,應使用常量或確定有值的對象來調用 equals。 正例: “test”.equals(object)
- 所有的相同類型的包裝類對象之間值的比較,全部使用 equals 方法比較。
- 定義 DO/DTO/VO 等 POJO 類時,不要設定任何屬性默認值。
- 序列化類新增屬性時,請不要修改 serialVersionUID 字段,避免反序列失敗;如 果完全不兼容升級,避免反序列化混亂,那麼請修改serialVersionUID值。序列化類新增屬性時,請不要修改serialVersionUID字段,避免反序列失敗;如果完全不兼容升級,避免反序列化混亂,那麼請修改 serialVersionUID 值。
- 構造方法裏面禁止加入任何業務邏輯,如果有初始化邏輯,請放在 init 方法中。
- POJO 類必須寫 toString 方法。使用 IDE 的中工具:source> generate toString 時,如果繼承了另一個 POJO 類,注意在前面加一下 super.toString。 說明:在方法執行拋出異常時,可以直接調用 POJO 的 toString()方法打印其屬性值,便於排 查問題。
- 類內方法定義順序依次是:公有方法或保護方法 > 私有方法 > getter/setter 方法。
- 循環體內,字符串的聯接方式,使用 StringBuilder 的 append 方法進行擴展。
- final 可提高程序響應效率,聲明成 final 的情況: 1) 不需要重新賦值的變量,包括類屬性、局部變量。 2) 對象參數前加 final,表示不允許修改引用的指向。 3) 類方法確定不允許被重寫。
4. 集合處理
- 關於 hashCode 和 equals 的處理,遵循如下規則: 1) 只要重寫 equals,就必須重寫 hashCode。 2) 因爲 Set 存儲的是不重複的對象,依據 hashCode 和 equals 進行判斷,所以 Set 存儲的 對象必須重寫這兩個方法。 3) 如果自定義對象做爲 Map 的鍵,那麼必須重寫 hashCode 和 equals。 正例:String 重寫了 hashCode 和 equals 方法,所以我們可以非常愉快地使用 String 對象 作爲 key 來使用。
- ArrayList的subList結果不可強轉成ArrayList,否則會拋出ClassCastException異常:java.util.RandomAccessSubList cannot be cast to java.util.ArrayList 。
- 使用集合轉數組的方法,必須使用集合的 toArray(T[] array),傳入的是類型完全 一樣的數組,大小就是 list.size()。直接使用 toArray 無參方法存在問題,此方法返回值只能是 Object[]類,若強轉其它 類型數組將出現 ClassCastException 錯誤。
- 使用工具類Arrays.asList()把數組轉換成集合時,不能使用其修改集合相關的方法,它的add/remove/clear方法會拋出 UnsupportedOperationException 異常。 asList 的返回對象是一個 Arrays 內部類,並沒有實現集合的修改方法。Arrays.asList 體現的是適配器模式,只是轉換接口,後臺的數據仍是數組。
- 不要在 foreach 循環裏進行元素的 remove/add 操作。
- 利用 Set 元素唯一的特性,可以快速對一個集合進行去重操作,避免使用 List 的 contains 方法進行遍歷、對比、去重操作。
第二章 基礎篇
1.單據信息
獲取卡片和列表容器(Panel)
卡片
UI端:getBillCardPanelWrapper().getBillCardPanel()或者getBillCardPanel()
EventHandler:getBillCardPanelWrapper().getBillCardPanel()
列表
UI端:getBillCardPanelWrapper().getBillListPanel()或者getBillListPanel()
EventHandler:getBillCardPanelWrapper().getBillListPanel()當前界面卡片/列表狀態
getBillManageUI().isListPanelSelected()
獲取/設置當前單據的操作狀態
getBillUI().setBillOperate(intnewBillOperate);
getBillUI().getBillOperate()獲取選擇的樹節點
getBillTreeCardUI().getBillTreeSelectNode();
getBillTreeCardUI().getBillTreeSelectNode().getData();是否單表體
isSingleDetail() true:爲單表體;false:爲單表頭;(在校驗類裏)
設置單據卡片表頭區域比例
((nc.ui.pub.bill.BillCardLayout)getBillCardPanel().getLayout()).setHeadScale(80);
設置表體頁籤狀態
顯示狀態:getBillCardPanel().getBodyPanel(“”).setVisible(false);
可用狀態:getBillCardPanel().getBillModel(“subbillb”).setEnabled(false);
當前頁籤編碼:getBillCardPanelWrapper().getBillCardPanel().getCurrentBodyTableCode()獲取單據模板上定義的所有字段
nc.vo.pub.bill.BillTempletBodyVO[] tbodyvos =
(nc.vo.pub.bill.BillTempletBodyVO[]) billCardPanel.getTempletData().getChildrenVO();列表啓用表頭多選對話框
getBillListPanel().setParentMultiSelect(true);
VO的獲取
EventHandler中可以直接調用,可以獲取單據對應的緩存數據,getBufferData().getCurrentVO()卡片下爲獲取當前單據的VO對象,列表下則爲獲取當前選擇行的VO對象。UI類當和EventHandler類在同一個包下時,也可以直接調用該方法。當UI類與EventHandler類不在同一個包下時,可以通過getManageEventHandler()獲取EventHandler對象,然後再調用EventHandler的getBufferData()獲取緩存數據。
界面取值
得到單據表體當前被選中的VO:getBillCardPanelWrapper().getSelectedBodyVOs(); //如果沒有被選擇的行那麼返回NULL
從界面上得到VO
getBillCardPanelWrapper().getBillVOFromUI();//得到界面上全部數據的VO
getBillListWrapper().getVOFromUI()//被選擇行的VO得到界面變化數據的VO
(ClientUI)getChangedVOFromUI()或者getBillListWrapper().getChangedVOFromUI()
通過VO的className
卡片
getBillCardPanel().getBillData().getBillValueVO(billVOName, headVOName, bodyVOName)
getBillCardPanel().getBillData().getBillValueChangeVO(billVOName, headVOName, bodyVOName)
列表
getBillListPanel().getBillListData().getBillSelectValueVO(billVOName, headVOName, bodyVOName)
getBillListPanel().getBillListData().getBillSelectValueVOs(billVOName,headVOName, bodyVOName)
getBillListPanel().getBillListData().getBillValueVO(row, billVOName, headVOName, bodyVOName)通過PK值查詢
InvbasdocVOinvbasdocVO=(InvbasdocVO)HYPubBO_Client.queryByPrimaryKey(InvbasdocVO.class, pk_inv);
設置Buffer中的TS到當前設置VO:
(ClientUI)getChangedVOFromUI()或者getBillListWrapper().getChangedVOFromUI()
得到當前VO的一個副本:
getBufferData().getCurrentVOClone()
刷新某一行的VO
BillManageUI.getBillListWrapper().updateListVo(hvo, selectedRows[i]);
2.數據庫操作
SuperVO
針對SuperVO,通用的方式爲下面兩種。如果是特殊的單據如供應鏈等需要特殊的操作,不能使用下面的方法
前臺:HYPubBO_Client
後臺:BaseDAO(供應鏈)的GeneralBillHelper類
ret = GeneralBillHelper.queryBills(單據類型, (QryConditionVO)voCond);
表頭字段值
取值
getBillCardPanel().getHeadItem(“strKey”).getValueObject()
表頭VO.getAttributeValue(‘”字段名”);
賦值
表頭VO.setAttributeValue(“字段名” ,值); 聚合VO.setHeaderValue(“字段名” ,值);
getBillCardPanel().setHeadItem(“字段名” ,值);表體字段值
獲取
getBillCardPanelWrapper().getBillCardPanel().getBodyValueAt(rowIndex, “strKey”)。其中rowIndex爲要獲取字段所在的行。
卡片下獲取表體相應頁簽下的字段:getBillCardPanel().getBodyItem(“plh_topics_b2”, “nitemmny”)
獲取單據模板上定義的所有字段:
nc.vo.pub.bill.BillTempletBodyVO[] tbodyvos = nc.vo.pub.bill.BillTempletBodyVO[]) billCardPanel.getTempletData().getChildrenVO();
賦值
爲表體某行某個字段賦值:
聚合VO.setItemValue(行索引值, “字段名”, 值);
getBillCardPanel().setBodyValueAt(aValue, row, strKey);
aValue:爲要賦的值; row:爲所在的行;strKey:爲字段名;
注意:
得到表體上的值,得到的類型是object類型的。要進行一下轉換(),但是不能直接轉:如下getBillCardPanel().getHeadItem(“字段名”).getValueObject().toString();這樣轉是容易出錯。正確定的轉換方式爲:Object obj = getBillCardPanel().getHeadItem(“pk_npic_schedule_id”).getValueObject();
String pk_contract=obj==null?”“:obj.toString();字段設置可編輯:
getBillCardPanel().getBodyItem(“字段名”).setEdit(true);
隱藏字段
getBillCardPanel().hideBodyTableCol(“bodyitem”);
代碼設置卡片狀態下表頭和表體某一字段的編輯狀態:
// 表頭
getBillCardPanel().getHeadItem(“”).setEdit(false);
// 表體
getBillCardPanel().getBillModel().setCellEditable(row,”nqichunum”,false);
3.其他
獲取表體選擇行
獲取表體的選中行的行號getBillCardPanelWrapper().getBillCardPanel().getBillTable().getSelectedRow();或getBillCardPanelWrapper().getBillCardPanel().getBodyPanel().getTable().getSelectedRow();
獲取編輯行getBillCardPanelWrapper().getBillCardPanel().getBillTable().getEditingRow()
獲取總行數getBillCardPanelWrapper().getBillCardPanel().getBillTable().getRowCount()
獲取列表多條記錄的方法
1.int[] selectRows = ((BillManageUI) getBillUI()).getBillListPanel().getHeadTable().getSelectedRows();
2.((BillManageUI)getBillUI()).getBillListPanel().getHeadBillModel().getBodySelectedVOs(DemoYsHVO.class.getName());
其中,方法1只在Ctrl、Shift多選時能取到多條記錄的行號。方法2都能取到多選記錄的VO。常量的獲取(公司,操作員,時間)
得到當前登錄公司的主鍵(UI):
ClientEnvironment.getInstance().getCorporation().getPrimaryKey();
getClientEnvironment().getCorporation().pk_corp.toString();
得到當前登錄用戶的主鍵(UI):
ClientEnvironment.getInstance().getUser().getPrimaryKey();
公司主鍵:ClientEnvironment.getInstance().getCorporation().getPrimaryKey();
getBillUI()._getCorp().getPrimaryKey();
操作員主鍵:ClientEnvironment.getInstance().getUser().getPrimaryKey();
getBillUI()._getOperator();
服務端時間:ClientEnvironment.getServerTime();
getBillUI().getServerTime();
SFServiceFacility.getServiceProviderService().getServerTime().toString()
客戶端日期:ClientEnvironment.getInstance().getDate();
getBillUI().getDate();單據保存時強制調用非空驗證方法:
getBillCardPanelWrapper().getBillCardPanel().dataNotNullValidate()
在編輯事件中常用的判斷
判斷是不是對錶體進行的編輯: e.getPos()==IBillItem.BODY或者e.getPos()==0
判斷是不是對錶體進行的編輯: e.getPos()==IBillItem.HEAD或者e.getPos()==1
判斷是對單據上哪個字段進行的編輯: “字段名“.equals(e.getKey());字段設置可編輯:
getBillCardPanel().getBodyItem(“字段名”).setEdit(true);
字段設置可編輯:
getBillCardPanel().getBodyItem(“字段名”).setEdit(true);
後續繼續補充…