智慧領域物件設計(演繹革命)-1/2
本文原始碼
關於智慧領域物件的設計,一直沒有拿出確實的例子來說明這樣程式設計的好處和優點,以及如何正確地理解這種程式設計方式。接下來我開始從傳統Service + DAO開發模式開始改造和發展,直到變化成智慧領域物件設計的開發模式上來,對於每一種變化,我會統計出手工程式碼編寫行數(setter 、getter和import等就不在統計範圍內了),看看生產力的變化。任何生產力的提高都是體現在機械代替重複而又規律的工作上,我們選擇的案例同樣是本應該被工業化掉的東西,但還在手工勞作。
傳統的Service + DAO包括三個核心類,以“使用者”物件為例,通常包括的類:User, UserService, UserDAO。通常需要的外部支援是:hibernate/jpa,spring。為了演示方便忽略掉介面(如IUserService),也不再區分PO和VO。事實上案例演示完成後,你會發覺這兩個東西確實很少使用。
這個例項中包含了一個持久層框架Thin,我先將有關持久的論述寫在這裡,你可以先看例項回頭有興趣再這段內容:所謂物件的持久就是把物件的屬性登記在資料庫中,在現實生活是經常發生的,如我們去銀行辦一個儲蓄卡,需要填表,而填表的過程就是持久化的過程。看看這張表格,便會發現所有填寫項都可以用key-value表示,再考察我們是如何區分現實物件,便會發現同樣是以物件的屬性為區分依據,屬性就可以用key-value表示,所以無論任何物件只要被持久必然可轉化成key-value,唯一的不同就是key-value的儲存方法不同而已,即:key-value是一切物件持久的介面。如果應用程式的持久方式是基於key-value的,那麼這種應用不僅便於更換不同的關聯式資料庫,即使是往NO-SQL資料庫上移植,縱然我對No-SQL資料庫不甚瞭解,但它絕不會偏離本質。Thin就是這麼一個工具,把物件轉化成key-value,然後存入對應的表,反之亦可。科學家通常用習慣用“美”來衡量結論正確性,雖然沒有什麼科學依據,但也屢試不爽。key-value是一切物件持久的介面,這個結論是美的,大家可以順便考量一下thin的短小精幹是否也符合美的標準。”大道若簡”,我相信基於key-value的持久方式,正是持久層的“大道”。
User類改動前User.java:
@Entity @Table(name=”user”) public class User{ @Id private String uid; private String uname; private String password; private String gid;//機構ID private String gname;//機構名稱 private String rid;//角色ID private String rname;//角色名稱 //setter and getter } UserService.java /** * spring的配置忽略 * * <bean id="UserService" class="com.icitic.zero.service.impl.UserService"> <property name="userDao" ref="userDao"/> </bean> * @author haihong * */ public class UserService { private UserDAO userDao; public void addUser(User user) { try { this.userDao.add(user); } catch (Exception e) { throw new RuntimeException(e); } } public User getUser(String id) { try { this.userDao.getUserById(id); } catch (Exception e) { throw new RuntimeException(e); } return null; } public void updateUser(User user) { try { this.userDao.update(user); } catch (Exception e) { e.printStackTrace(); } } public void deleteUser(Collection<User> users) { try { User[] us = new User[users.size()]; users.toArray(us); this.userDao.delete(us); } catch (Exception e) { e.printStackTrace(); } } public void saveOrUpdate(User user) { try { this.userDao.save(user); } catch (Exception e) { e.printStackTrace(); } } public UserDAO getUserDao() { return userDao; } public void setUserDao(UserDAO userDao) { this.userDao = userDao; } } UserDAO.java /** * <bean id="UserDAO" class="com.icitic.zero.dao.UserDAO"> <property name="sessionFactory" ref="sessionFactory"/> </bean> * * * @author haihong * */ public class UserDAO extends HibernateDaoSupport{ public void add(User user) { getHibernateTemplate().save(user); } public User getUserById(String id) { return (User) getHibernateTemplate().load( User.class, id); } public void update(User user) { getHibernateTemplate().update(user); } public void delete(User... user) { getHibernateTemplate().delete(user); } public void deleteById(String uid) { User user = this.getUserById(uid); getHibernateTemplate().delete(user); } public void save(User user) { getHibernateTemplate().saveOrUpdate(user); } } <p class="indent"> |
1.編碼量統計:
User.java 11行
UserService.java 56行
UserDAO.java 21行
共88行
開始用thin(基於key-value的持久層框架)改造:
User.java
@BeanTableName(name="z_user") public class User{ @Primary private String uid; private String uname; private String password; private String gid;//機構ID private String gname;//機構名稱 private String rid;//角色ID private String rname;//角色名稱 //setter and getter } <p class="indent"> |
替換類和主鍵的註解換成thin的註解,其他不變.
UserService.java
public class UserService extends BaseService { public void addUser(User user) { try { this.add(user); } catch (Exception e) { e.printStackTrace(); } } public User getUser(String id) { try { List users = this.getObject(User.class,SQLCriterion.get("uid", id)); if(users.isEmpty()){ return (User)users.get(0); } } catch (Exception e) { e.printStackTrace(); } return null; } public void deleteUser(User user) { try { this.deleteObject(user); } catch (Exception e) { e.printStackTrace(); } } public void deleteUser(String uid) { try { User user = (User)this.getObject(User.class, SQLCriterion.get("uid", uid)); this.deleteUser(user); } catch (Exception e) { e.printStackTrace(); } } public void deleteUser(Collection<User> users) { Collection<String> uids = new ArrayList(); for (User u : users) { uids.add(u.getUid()); } try { getBeanTable(User.class).delete(SQLCriterion.get("uid", Operator.IN, uids)); } catch (Exception e) { e.printStackTrace(); } } public void saveOrUpdate(User user) { try { ThinContext.ctx.beginTransaction(); this.deleteUser(user); this.addUser(user); ThinContext.ctx.commitTransaction(); } catch (SQLException e) { try { ThinContext.ctx.rollback(); } catch (SQLException e1) { } throw new RuntimeException(e); } } } <p class="indent"> |
UserDAO.java不再需要,所有類似與此的DAO都不需要了,BaseService 已經為物件的持久提供好了介面,只需要呼叫即可。
2.編碼量統計:
User.java 11行
UserService.java 60行
UserDAO.java 0行
編碼量合計:71行
如此改進會減少88-71=17行程式碼和一個Dao類。
同時可以放一放hibernate/jpa這個朋友了,而且可以減少與spring的瓜葛。說真的,使用Service+DAO這種方式程式設計,有類似spring這樣的管理工具,還是真是輕鬆了不少,但是spring所提供的依賴管理方式只是讓我們更加舒適地適應了傳統,但是原來要寫程式現在幾乎還要寫。
我們再進一步用採用物件導向的思想(智慧領域物件設計)來改造這個模組,讓有User繼承ThinObject:
@BeanTableName(name="z_user") public class DomainUser extends ThinObject{ @Primary private String uid; private String uname; private String password; private String gid;//機構ID private String gname;//機構名稱 private String rid;//角色ID private String rname;//角色名稱 //所有的增刪改查父類已經提供了 //setter and getter } <p class="indent"> |
不再需要UserServiceT.java了,像這種增刪改查的功能,ThinObject已經提供了。
3.編碼量統計:
DomainUser.java 11行
UserServiceT.java 0行
UserDAO.java 0行
合計:11行
程式碼編寫量從88行降到11行。減少87.5%的工作量。以30類為例,就少寫2310行程式碼,少建60個類.
大家可以根據自己的工作效率算算,會節省多少天的工作量。從此單表的DAO操作就可以不用再寫,也不用建立對應增刪改查的類了。
當然這個例子有些極端,但是並不影響它在提高生產力的方面的不錯表現。讀到這裡你可以會有一個疑問,我們應該如何處理物件之間的關係,如一對多,或者多對多。複合物件是由簡單物件組成的,既然簡單的儲存已經很方便地解決了,複合物件也水到渠成地解決了。
智慧領域物件設計還有個特性,是支援因果事件模式,模擬因果傳遞。我在下一篇例項中詳解!
下一篇:智慧領域物件設計(例項講解)
[該貼被cuwkuhaihong於2010-08-09 13:20修改過]
相關文章
- 智慧領域物件設計物件
- 智慧領域物件設計(例項講解)-2/2物件
- JdonMVC+JDON+CQRS演繹智慧物件MVC物件
- 領域驅動設計戰術模式--值物件模式物件
- 戲說領域驅動設計(二十)——值物件物件
- 系統領域物件設計,希望大家探討物件
- redux 流程演繹Redux
- 領域物件與業務邏輯關係設計思路物件
- DDD領域驅動設計:領域事件事件
- DDD-領域物件與領域服務物件
- 理性演繹模型(轉載)模型
- 領域驅動設計戰術模式--領域事件模式事件
- 戲說領域驅動設計(廿五)——領域事件事件
- 中國汽車生態演進:智慧出行領域趨勢盤點
- 領域驅動設計戰術模式--領域服務模式
- 理解領域驅動設計
- MasaFramework -- 領域驅動設計Framework
- 領域驅動設計示例
- 以乾坤之道演繹精彩IT人生
- 超越三星,華為再與蘋果演繹智慧手錶江湖蘋果
- DDD領域驅動設計初探(2):倉儲Repository(上)
- 領域驅動設計簡介
- 實現領域驅動設計
- 領域驅動設計核心概念
- 人工智慧商務服務領域應用前景演講(附PPT)人工智慧
- 在複雜領域中設計軟體:領域驅動設計 - levelup
- 物聯網智慧家居領域的測試用例設計思路?
- 物件導向與領域建模物件
- js能替代領域物件嗎?JS物件
- 《實現領域驅動設計》筆記——領域、子域和限界上下文筆記
- JavaScript中的領域驅動設計JavaScript
- 淺談DDD(領域驅動設計)
- 微服務領域驅動設計 - semaphoreci微服務
- 淺談 DDD 領域驅動設計
- 前端開發-領域驅動設計前端
- 領域驅動設計中的模型模型
- DDD-領域驅動設計示例
- 實驗2 類和物件 基礎程式設計1物件程式設計