2007年6月20日
#
很不錯的一個UML建模工具-argouml
argouml下載地址
我一眼就看上他的原因是:生成的用例和包圖可能直接生成JAVA代碼,而且準備無誤,這正是我要找的。
我想:以后使用一些框架的話,可能由PD生成一些實體,然后Hibernate生成pojo等,加入到argouml,然后根據一個框架的特性生成一些包
和類.就等于詳細設計了吧.應該來說是比詳細設計還實用的東西.總比哪些WORD文檔好吧.還有讓人看不懂的概要設計.
我想從技術出發,這個是一條比較適用的路子.下班了.我明天將會匯報一下我使用的情況和一些范例.
反過來又想像.這好象是一個組合的腳手架.好象ROR的零星操作步驟.應該學習.ROR畢竟是一個新生事物,JAVAEYE的推廣也需要一個時間.如果像我這樣的打工,混口飯吃的人還是專心的研究J2EE好一點.否則明天就沒有飯吃了.
呵呵.我的文章可被JAVAEYE收回到水貼里了,可能自己的能力不如人吧,好好學習,天天向上,如果看客有什么好的工具和軟件生產思路,可以共同交流。
2006年9月29日
#
今天學習了一下ROR,有一些學習經驗東西要與大家分享。
給ROR加一個座右銘--------狹窄心腸的日本產物。
首先,不要一個一個的下載Ruby,Rails,建議使用一鍵安裝,下載地址如下:
InstantRails-1.3-win
版本說明:ruby 1.8.4 (2005-12-24) [i386-mswin32]
其次,下載一個目前為止比較好的一個ROR的實踐工具:RadRails
下載地址:radrails-0.7.1-win32
接下來,設置一下Radrails的環境
1)、Windows/perferences/Ruby/Installed Inteperters/ ->add ruby所在路徑:比如D:\InstantRails\ruby\bin\ruby.exe
2)、Windows/perferences/Rails/Configuration ->Rails path:比如D:\InstantRails\ruby\bin\rails
->Rake path:比如D:\InstantRails\ruby\bin\rake 絕不是bat/cmd
->mogrel path:比如D:\InstantRails\ruby\bin\mongrel_rails絕不是bat/cmd
有了如上的配置后,就只需要和在JAVA當中ANT一樣使用。(成功用過APPFUSE的人就不用害怕了)
看看日本人寫的第一步:
1),在RadRails中創建一個Rails Project,怎么樣會出來一堆的東東。
2),進入DOS命令吧,后面的工序都是這樣的,好象買了海爾的洗衣機,第一次是送貨、第二次是用戶回訪,第三次是.....
進入到你的項目處,運行ruby script\generate controller MyTest,
則得到的服務如下:
exists app/controllers/
exists app/helpers/
create app/views/my_test
exists test/functional/
create app/controllers/my_test_controller.rb
create test/functional/my_test_controller_test.rb
create app/helpers/my_test_helper.rb
修改一下my_test_controller.rb
代碼
??????
class
?MyTestController?
<
?ApplicationController
??????def?index
????????render_text?
"
Hello?world!!
"
??????end?
??????end
在瀏覽器里輸入:http://127.0.0.1:3000/my_test/
會出現 Hello world!!字樣,
不過有意思的是你可以輸入:http://127.0.0.1:3000/My_test/
http://127.0.0.1:3000/My_Test/
http://127.0.0.1:3000/my_Test/
都可以得到這個值,可能沒有JAVA哪樣嚴格吧。
3)、還有對數據庫的操作,要配置一個database.yml(好象Log4j的東東)
4)、創建數據庫表的時候只能夠使用復數起名,比如User就不行,只能夠起Users
下面只要執行幾個命令就可以使用增刪改查了。
如下是我的操作,下班了,就不多寫了,例子能夠說明一切問題:
代碼
?1?E:\RORProject\demo>ruby?script/generate?model?user
?2?
?3???????exists??app/models/
?4?
?5???????exists??test/unit/
?6?
?7???????exists??test/fixtures/
?8?
?9???????create??app/models/user.rb
10?
11???????create??test/unit/user_test.rb
12?
13???????create??test/fixtures/users.yml
14?
15???????exists??db/migrate
16?
17???????create??db/migrate/001_create_users.rb
18?
19?E:\RORProject\demo>ruby?script/generate?controller?user
20?exists?app/controllers/
21?exists?app/helpers/
22?create?app/views/user
23?exists?test/functional/
24?create?app/controllers/user_controller.rb
25?create?test/functional/user_controller_test.rb
26?create?app/helpers/user_helper.rb
27?
修改user_controller.rb如下:
代碼
1????class?UserController?<?ApplicationController
2????????scaffold:user
3????end
最后你的瀏覽器當中輸入:http://127.0.0.1:3000/user/list,就包括了對數據庫表的四個操作.當然你也可以自己定義四個操作的任意一種.
最后總結:
ROR可能是敏捷開發的一個好實踐,但是我覺得他完成復雜應用進不會有大做為,而至于這一點還需要再做探究。不過現階段最好的需求就是能夠給用戶快速的寫出一個不完整的DEMO,這一點為以后打單取得主動。
摘要: 只需要你三個JAVA類和兩個配置文件,就可以完成你的MVC應用,我們就做一個示例吧。本文以一個登錄為例。第一個JAVA文件Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->/**======================================...
閱讀全文
2006年9月25日
#
在項目開發的很多時候,用戶需要更友好,更容易理解的操作界面,而為了能夠達到這種表現界面,struts標簽顯得力不從心,本人經過幾個項目的開發當中 逐漸的擯棄了struts標簽,而由JSTL來做為JSP頁面的表達者。
struts標簽之死穴一 不支持嵌套
看看這種常見的需求吧。一個用戶隸屬于一個職能部門,比如
項目要求 職能部門有五個(亂寫的)
1、企劃部
2、網絡集成部
3、行政部
4、營銷部
5、產品部
項目要求 一共有二個員工
1、張三 隸屬于行政部
2、李四 隸屬于營銷部
而你想把張三和李四都列表出來,顯示為如下:
姓名 部門名稱
張三 行政部
李四 營銷部
而且還需要用戶的列表鏈接到修改頁面當中(假如只修改部門)應該如何做呢。
在使用struts標簽是很難做到的,除非你非常不在意內存的使用(亂寫技術性代碼)
看看JSTL是如何做的吧。
從STRUTS的ACTION當中加載兩個對象
List?GetAllDept?
=
?UserDAO.GetAllDept();
//
取得所有部門
List?GetALLUser?
=
?UserDAO.GetAllUser();
//
取得所有用戶
request.setAttribute(
"
View_Dept
"
,?GetAllDept);
request.setAttribute(
"
View_User
"
,?GetALLUser);
在頁面當中加入對JSTL的引用
<%@?taglib?uri="http://java.sun.com/jsp/jstl/core"?prefix="c"%>
然后寫代碼如下:
<table>
<tr>
<td?align="center">
<a?href="User.do?method=EditUser&UserId=<c:out?value='${View_User.UserId}'/>">
<c:out?value="${View_User.UserName}"?/>?</a>
</td>
<td?align="center">
<c:forEach?items="${View_Dept}"?var="View_Dept">
<c:if?test="${View_User.Dept.DeptId==View_Dept.DeptId}">
<c:out?value="${View_Dept.DeptName}"?/>
</c:if>????????????????????????????
</c:forEach>
</td>
</tr>
</table>
其中View_User.Dept.DeptId表示USER表與DEPT表的一個關系(外鍵)
你就可以看到所顯示的列表了。
還有如果在修改用戶時,則也與上面的差不多,首先在ACTION當中加入:
String?ModifyUserId?=?request.getParameter("GroupUserId");
if?(ModifyUserId?==?null?&&?ModifyUserId.equals(""))?{
//這是出錯處理
request.setAttribute("UserMsg",?"User.ValidateUser");
return?mapping.findForward("Fail");
}
DynaValidatorForm?UserActionForm?=?(DynaValidatorForm)?form;
User?user?=?UserDAO.GetUser(ModifyUserId);????????
List?GetAllDept?=?UserDAO.GetAllDept();//取得所有部門
request.setAttribute("View_Dept",?GetAllDept);
UserActionForm.set("User",?User);
然后頁面當中顯示如下(部門為LISTBOX),例子當中只顯示部門
<html:select?property="DeptAsString">????????????
<c:forEach?items="${View_Dept}"?var="View_Dept">????????
<c:choose>????????????????????????
<c:when?test="${User.Dept.DeptId==View_Dept.DeptId}">
<option????value="<c:out?value='${View_Dept.DeptId}'?/>"selected>????
<c:out?value="${View_Dept.DeptName}"?/>????????????
</option>????????????????????????????
</c:when>????????????????????????????
<c:otherwise>????????????????????????
<option?value="<c:out?value='${View_Dept.DeptId}'?/>">????????
<c:out?value="${View_Dept.DeptName}"?/></option>????????
</c:otherwise>????????????????????????
</c:choose>
</c:forEach>
</html:select>
可以看到HTML的SELECT有一個DeptAsString,你可以在FORM當中指定一個STRING的FORM屬性。
這樣用戶的要求就可以完成了。
本次只說明方法,而代碼沒有經過測試。希望大家多多觀注我的BLOG,下一次將臭罵ACTIONFROM不支持的DATE類型及解決方法。
2006年9月5日
#
摘要: 在大家的編碼過程當中,有沒有遇到過這么一種情況,很多零亂的狀態、分類和其它常用選項常常是定義死了。但是沒有一個完整的東東來約束他,在每個模塊當中使用相關的信息時,往往重新COPY一次,或者COPY過來修改一次。如果多人協作的話,務必會讓代碼變的零亂、不好管理等。
本次主要是把一些靜態的分類、狀態或者其它常用選項使用二維數組管理起來。如果你是一個使用JSTL或者STRUTS做前臺表現的話,你就更應該好好關注了.......
閱讀全文
2006年7月21日
#
??? struts表單主要是利用actionform來取得JSP頁面所有的request的,所有的Struts標簽無非在取得request當中的所有INPUT,并賦值回標簽值的,同理,JSTL能夠在JSP表單當中輕易的表現要輸出的結果。
??? 如果你是高手,你就知道這個標題有誤,是的,struts表單與JSTL表現沒有可比性,但是如果我們要在實現一個多條件的查詢頁面時,這個比較就比較有效了。
??? 我不妨比較一下利用struts表單的查詢實現 和 利用JSTL做為表現而實現的查詢功能有什么不同,讓讀者尋其方便。
??? 示例說明:
??? 用戶表-USER
??? username? 用戶名稱
??? loginid?? 登錄ID
??? sex?????? 性別
??? 一、利用struts表單的查詢實現
??????? 實現步驟:
??????? 創建多條件的序列化對象(java)->在struts.config當中申明actionform->Action當中實現->輸出結果
???????
????/**?The?value?of?the?simple?userName?property.?*/
????private?java.lang.String?userName;
????/**?The?value?of?the?simple?loginId?property.?*/
????private?java.lang.String?loginId;
????/**?The?value?of?the?simple?sex?property.?*/
????private?java.lang.String?sex;
????/**
?????*?Return?the?value?of?the?USER_NAME?column.
?????*?@return?java.lang.String
?????*/
????public?java.lang.String?getUserName()
????{
????????return?this.userName;
????}
????/**
?????*?Set?the?value?of?the?USER_NAME?column.
?????*?@param?userName
?????*/
????public?void?setUserName(java.lang.String?userName)
????{
????????this.userName?=?userName;
????/**
?????*?Return?the?value?of?the?LOGIN_ID?column.
?????*?@return?java.lang.String
?????*/
????public?java.lang.String?getLoginId()
????{
????????return?this.loginId;
????}
????/**
?????*?Set?the?value?of?the?LOGIN_ID?column.
?????*?@param?loginId
?????*/
????public?void?setLoginId(java.lang.String?loginId)
????{
????????this.loginId?=?loginId;
????}
????/**
?????*?Return?the?value?of?the?sex?column.
?????*?@return?java.lang.String
?????*/
????public?java.lang.String?getSex()
????{
????????return?this.sex;
????}
????/**
?????*?Set?the?value?of?the?sex?column.
?????*?@param?loginId
?????*/
????public?void?setSex(java.lang.String?sex)
????{
????????this.sex?=?sex;
????}
<!-- struts_fonfig -->
??????? <form-bean?name="UserActionForm"?type="org.apache.struts.validator.DynaValidatorForm">
<form-property?name="userCondition"?type="com.antbee.searchCondition.UserFindCondition"?/>????????
????????</form-bean>
Action當中
DynaValidatorForm?UserForm?=?(DynaValidatorForm)?form;
????????UserFindCondition?Condition?=?(UserFindCondition)?UserActionForm
????????????????.get("userCondition");//?取得查詢條件
List?user?=?userManager.find(Condition,
????????????????(iCurPageNo?-?1)?*?pageCon.PAGE_SIZE,?pageCon.PAGE_SIZE);//呵呵,加入了hibernate的分頁
具體實現:
????public?List?find(UserFindCondition?Condition,?int?begin,
????????????int?count)?{
????????StringBuffer?sql?=?new?StringBuffer("from?User?as?a?where?1=1");??????????????
? ? ? ? if?(Condition?!=?null)?{
????????????makeSql(sql,?shipmentFindCondition);
????????}
????????String?fsql?=?sql.toString();
????????Query?query?=?this.getSession().createQuery(fsql);
????????if?(Condition?!=?null)?{
????????????setParameter(query,?Condition);
????????}
????????query.setFirstResult(begin);
????????query.setMaxResults(count);
????????List?tt?=?query.list();
????????return?tt;
????}
--
??? /**
??? ?* 根據條件生成一個sql語句
??? ?*
??? ?* @author 和
??? ?* @param sql
??? ?*??????????? 初始的sql語句(一般為select a from A as a where 1=1)
??? ?* @param condition
??? ?*??????????? 查詢的條件
??? ?* @return
??? ?* @version 1.0
??? ?*/
private?void?makeSql(StringBuffer?sql, UserFindCondition?condition)?{
????????if?(condition.getUsername()?!=?null
????????????????&&?!condition.getUsername().toString().equals(""))?{
????????????sql
????????????????????.append("?and a.username like?:username");
????????}
????????if?(condition.getLoginid()?!=?null
????????????????&&?!condition.getLoginid(().equals(""))?{
????????????sql
????????????????????.append("?and a.loginid( =?:loginid(");
????????}
????????if?(condition.getSex()?!=?null
????????????????&&?!condition.getSex().equals(""))?{
????????????sql.append("?and a.sex =?:sex");
????????}
????}
????/**
?????*?根據條件設置query的值
?????*?
?????*?@author?和
?????*?@param?query
?????*????????????一個hibernate的Query對象
?????*?@param?condition
?????*????????????查詢的條件
?????*?@return
?????*?@version?1.0
?????*/
????private?void?setParameter(Query?query, UserFindCondition?condition)?{
????????if?(condition.getUsername()?!=?null
????????????????&&?!condition.getUsername().equals(""))?{
????????????query.setString("username",?"%"?+?condition.getUsername()
????????????????????+?"%");
????????}
????????if?(condition.getLoginid()?!=?null
????????????????&&?!condition.getLoginid().equals(""))?{
????????????query.setString("loginid",?condition.getLoginid());
????????}
????????if?(condition.getSex()?!=?null
????????????????&&?!condition.getSex().equals(""))?{
????????????query.setString("sex",?condition.getSex());
????????}?????
????}
呵呵,笑死人了,這個方法很通用,我才在我的第二個項目當中才用到,真是可惜,當然了,使用Actionform有一個毛病就是對date類型要轉換成STRING類型來處理,這是actionform的一個死穴。還有對Actionform不能夠重置,只能夠回來從前。不知道這群設計者怎么想的,真是由于這一點,所以我們有必要使用最原始的方法來解決問題了。使用頁面當中的input,我們來拼request如何?
?? 二、利用JSTL做為表現而實現的查詢功能
???? 步驟:在JSP頁面布置很多的input,當然,你可以加入value了。(省略了...)
?????????? 創建查詢條件的序列化對象(同樣user.java)
?????????? 在action當中拼個condition了,做為查詢條件,后面的處理類同第一種方式。
?????UserSearchCondition?userSearchCondition?=?null;
?????userSearchCondition?=?makeUserSearchCondition(request);
private UserSearchCondition?makeUserSearchCondition(HttpServletRequest?request)?throws?Exception{
??????? UserSearchCondition userSearchCondition?=?new?OrderSearchCondition();
????????String username =?request.getParameter("Username");
????????String loginid =?request.getParameter("Loginid");
????????String sex =?request.getParameter("Sex");??
???????
????????????????
????????if(username!=?null?&&?!username.trim().equals("")){
??????????? usernameSearchCondition.setUsername(username);
????????}
????????
????????if(loginid? !=?null?&&?!loginid.trim().equals("")){
??????????? userSearchCondition.setLoginid (loginid );
????????}
????????
????????if(sex !=?null?&&?!sex.trim().equals("")){????????
??????????? userSearchCondition.setSex(sex);
????????}??????
????????
????????return userSearchCondition;
????}
???? 以后的方法,我就不用再做舉例了吧,可以參考如上第一種方法的實現.
???? 第二種方法的好處就是:在頁面上比較好控制,比如重置,又比如日期性數據等。
???? (所有過程當中的代碼沒有經過測試,只是說明這種方法而已)
呵呵,在忙一個項目,潛水很久,現在冒個泡:
(本文適用在struts+spring+hibernate3上做開發的蟲蟲們)
類名:HibernateUtil
package?com.antbee.j2eemodel.util;
import?java.lang.reflect.InvocationTargetException;
import?java.lang.reflect.Method;
import?java.util.Collection;
import?java.util.Iterator;
import?org.springframework.orm.hibernate3.support.HibernateDaoSupport;
public?class?HibernateUtil?extends?HibernateDaoSupport?{
/**
*?初始化POJO類
*?@author?@家軍
*?@param?object?POJO對象
*?@param?methodName?方法名稱
*?@return
*?@version?1.0
*/
public?void?initialize(Object?object,?String?methodName)?throws?SecurityException,?NoSuchMethodException,?IllegalArgumentException,?IllegalAccessException,?InvocationTargetException?{
String[]?methodArray?=?methodName.split("\\.");
Method?method?=?null;
Object?initializeObject?=?object;
if(methodArray.length?==?1){
this.getHibernateTemplate().lock(initializeObject,?org.hibernate.LockMode.NONE);
method?=?object.getClass().getMethod(methodArray[0],?new?Class[]?{});
initializeObject?=?method.invoke(initializeObject,?new?Object[]?{});
this.getHibernateTemplate().initialize(initializeObject);
}else{
for(int?i=0;i<methodArray.length;i++){
method?=?initializeObject.getClass().getMethod(methodArray[i],?new?Class[]?{});
initializeObject?=?method.invoke(initializeObject,?new?Object[]?{});
}
this.getHibernateTemplate().lock(initializeObject,?org.hibernate.LockMode.NONE);
this.getHibernateTemplate().initialize(initializeObject);
}
}
/**
*?初始化POJO類
*?@author?@家軍
*?@param?object?POJO對象
*?@param?methodName?方法名稱數組
*?@return
*?@version?1.0
*/
public?void?initialize(Object?object,?String?methodName[])
throws?SecurityException,?NoSuchMethodException,
IllegalArgumentException,?IllegalAccessException,?InvocationTargetException?{
for?(int?i?=?0;?i?<?methodName.length;?i++)?{
String[]?methodArray?=?methodName[i].split("\\.");
Method?method?=?null;
Object?initializeObject?=?object;
if(methodArray.length?==?1){
this.getHibernateTemplate().lock(initializeObject,?org.hibernate.LockMode.NONE);
method?=?object.getClass().getMethod(methodArray[0],?new?Class[]?{});
initializeObject?=?method.invoke(initializeObject,?new?Object[]?{});
this.getHibernateTemplate().initialize(initializeObject);
}else{
for(int?j=0;j<methodArray.length;j++){
method?=?initializeObject.getClass().getMethod(methodArray[j],?new?Class[]?{});
initializeObject?=?method.invoke(initializeObject,?new?Object[]?{});
}
this.getHibernateTemplate().lock(initializeObject,?org.hibernate.LockMode.NONE);
this.getHibernateTemplate().initialize(initializeObject);
}
}
}
/**
*?初始化POJO類
*?@author?@家軍
*?@param?object?POJO對象
*?@return
*?@version?1.0
*/
public?void?initialize(Object?object)?throws?SecurityException,?NoSuchMethodException,?IllegalArgumentException,?IllegalAccessException,?InvocationTargetException?{
this.getHibernateTemplate().lock(object,?org.hibernate.LockMode.NONE);
this.getHibernateTemplate().initialize(object);
}
/**
*?初始化POJO類
*?@author?@家軍
*?@param?collection?POJO對象集合
*?@param?methodName?方法名稱數組
*?@return
*?@version?1.0
*/
public?void?initialize(Collection?collection,?String?methodName[])
throws?SecurityException,?NoSuchMethodException,
IllegalArgumentException,?IllegalAccessException,?InvocationTargetException?{
for(Iterator?i=collection.iterator();i.hasNext()Wink{
Object?object?=?i.next();
this.initialize(object,methodName);
}
}
/**
*?初始化POJO類
*?@author?@家軍
*?@param?collection?POJO對象集合
*?@param?methodName?方法名稱
*?@return
*?@version?1.0
*/
public?void?initialize(Collection?collection,?String?methodName)
throws?SecurityException,?NoSuchMethodException,
IllegalArgumentException,?IllegalAccessException,?InvocationTargetException?{
for(Iterator?i=collection.iterator();i.hasNext()Wink{
Object?object?=?i.next();
this.initialize(object,methodName);
}
}
}?
這個方法的好外是:可以不在hbm.xml的文件當中,指定為lazy=true這個模式,可以直接使用。使用方法如下:
如果你使用SPRING,則需要把hibernateUtil注入其中:
?<bean?id="hibernateUtilTarget"?class="com.antbee.j2eemodel.util.HibernateUtil">
<property?name="sessionFactory">
<ref?local="mssqlSessionFactory"?/>
</property>
</bean>
<bean?id="hibernateUtil"?parent="BaseTransactionProxy"?class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property?name="target">
<ref?local="hibernateUtilTarget"?/>
</property>
</bean>
<!--配置基礎事務-->
<bean?id="BaseTransactionProxy"?class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"?abstract="true">
<property?name="transactionManager">
<ref?bean="mssqltransactionManager"?/>
</property>
<property?name="proxyTargetClass">
<value>true</value>
</property>
<property?name="transactionAttributes">
<props>
<prop?key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>?
使用示例:
如果你使用STRUTS,則需要這樣:
List?what_ur_view?=?XXXManager.find(

.);//取得你要展示的對象
//如果這個對象當中有延遲加載的對象(SET)時,則需要如下加載就行
this.hibernateUtil.initialize(what_ur_view,?"getTbShipmentSale");
//其中getTbShipmentSale是其對象(SET也可以操作)?
在頁面顯示的時候,你就可以使用JSTL如下表述:
<c:out?value="${what_ur_view.tbShipmentSale.goodsReceivePersonPhone}"?/>//呵呵,是不是很爽呀。?
同樣的方法,我們也可以對一個SET在頁面進行顯示,方法如下:
<c:forEach?items="${what_ur_view.tbShipmentProductMappingSet}"?var="ProductMapping"?varStatus="status">
<c:out?value="${ProductMapping.productNum}"?/>
<c:out?value="${ProductMapping.tbOutOfWarehouse.outOfWarehouseNum}"?/>
</c:forEach>
//呵呵,支持多級嵌套,?
在ACTION當中則需要加入hibernateUtil.initialize(what_ur_view.getTbShipmentProductMappingSet(),
new?String[]?{?"getTbProduct",?"getTbOutOfWarehouse",
"getTbProductConfigure"?});?
呵,如果你要是在HIBERNATE當中使用,這個就太簡單了吧。
怎么樣?呵呵呵,
從此,我對STRUTS的標簽深惡痛絕,而對JSTL情有獨鐘了。
2006年7月19日
#
?? 很長的時間陷入到與同事上級的斗爭當中,無聊死了,今天回來看看自己書簽當中的網站,感覺到自己是小人了。我不應該留戀明爭暗斗,我應該自立自強,永不停息。
?? 在年前的時候我曾經非常看好compiere的應用,想不到今天再看看國內使用的形勢,長三角和珠三角的廣泛應用,還有ORACLE免費數據庫的推出,更加印證了我錯誤的做法。
?? 一個人最重要的事情就是三個字:做決定。
?? 一個人想要成功,尤其像我這樣不甘愿給別人打工又有很多想法的人,除非是一種病態的堅持才能夠取得成功。
?? 我很討厭公司現行的CRM系統,簡單的說一句就是:簡直就是一個糊人的、丑陋的MIS系統,一點設計思想都沒有,一點產品理念都沒有。最重要的設計者在拼命的逃脫自己的責任,開發者在忍受莫大的痛苦,業務在每一個開發者思想里扭曲......唉,想抽出一點時間來都難。
?? 我要在以后的時候里,一則增加自己的業務能力,以compiere的應用為主;二則要增強我的技術能力,以
vTigerCRM為藍本,做一個J2EE的產品移植。
?? 在今年年底以前,自己必須要做到對compiere的應用熟練,能夠完成
vTigerCRM的J2EE實現。所以自己最重要要做的事是:時間安排,
2006年5月15日
#
來自于:http://blog.csdn.net/Raptor/archive/2006/05/13/727299.aspx
關于軟件開發的笑話有很多,下面這個是我剛在QQ群里的看到的:
1. 程序員寫出自認為沒有Bug的代碼。
2. 軟件測試,發現了20個Bug。
3. 程序員修改了10個Bug,并告訴測試組另外10個不是Bug。
4. 測試組發現其中5個改動根本無法工作,同時又發現了15個新Bug。
5. 重復3次步驟3和步驟4。
6. 鑒于市場方面的壓力,為了配合當初制定的過分樂觀的發布時間表,產品終于上市了。
7. 用戶發現了137個新Bug。
8. 已經領了項目獎金的程序員不知跑到哪里去了。
9. 新組建的項目組修正了差不多全部137個Bug,但又發現了456個新Bug。
10. 最初那個程序員從斐濟給飽受拖欠工資之苦的測試組寄來了一張明信片。整個測試組集體辭職。
11. 公司被競爭對手惡意收購。收購時,軟件的最終版本包含783個Bug。
12. 新CEO走馬上任。公司雇了一名新程序員重寫該軟件。
13. 程序員寫出自認為沒有Bug的代碼。
要我說,如果真有這樣的公司,不倒閉對不起人民。
這個笑話從程序員開始,到程序員結束,從頭到尾都在說程序員的不是。但是我要說的是,這完全是管理者的失敗,從整個過程中,看不到任何管理工作。這種管理者不但無知無能,還很無恥——將自己的失敗責任推給程序員。
1、程序員憑什么證明他的代碼沒有BUG?有Test case嗎?有Code review嗎?這個環節管理缺失。
2、測試發現BUG有進行BUG管理嗎?有跟蹤嗎?這個環節管理缺失。
3、憑什么證明程序員已經把那10個BUG修改好了?另10個又為什么不是BUG?BUG的評價標準難道是程序員說了算?這個環節管理缺失。
4、5個不能工作的BUG修改問題有沒有追究責任?增加新BUG是修改過程中不可避免的事情,但是如果有有效的單元測試機制,可以大大減少這種情況。這個環節管理缺失。
5、迭代是正常的,但是問題處理于發散而不是收斂發展,可見沒有有效的管理調控。這個環節管理缺失。
6、過于樂觀的時間表和不可能達到的最后期限,都表現出管理者的無知和無能。而在這樣的情況下強行推出產品,那就是無知者無畏了。
7、這是對用戶的不負責任,管理者要負最大的責任。
8、這樣的情況還能發項目獎金,只能說管理者不是一般的愚蠢。
9、管理工作沒有任何的改進,問題仍然處于發散迭代狀態。管理工作依然沒有到位。
10、拖欠測試部門工資體現出管理者對質量管理工作的忽視以及對人力資源管理方面一無所知。
11、送被收購者兩個字:活該。送收購者兩個字:瞎眼。
12、可見新管理者與原管理者半斤八兩,都沒有認識到問題的根本所在。不過也只有這樣的管理者才會作出收購這種公司的決策。
13、歷史的重演是必然的。
一個正常的企業或是項目,其運作必須應該是循環向上進行的。而保障這種運行的工作就是管理。而管理工作的主要內容就是控制,包括控制循環的節奏——不能太快也不能太慢,控制發展的方向——只能向上不能向下,控制運作的穩定——不能大起大落或時聚時散等。
而這一切,在這個例子中都看不到。
在 這個笑話的例子中,一切都是以開發工作在驅動,這首先就是一個方向性錯誤,產品是為用戶服務的,當然應該是以用戶和市場作為驅動,并且結合自身的能力最終 確定工作的重點。這一錯誤折射出管理者對被管理的內容很不了解,只好任由比較了解的程序員擺布——事實上他們除了技術,并不會了解更多。
一個管理者如果對自己所管理的內容不了解,他就不可能管理得好。
這是一件毫無疑問的事,可是國內的軟件業似乎總是不相信這一點。中國軟件業中流毒最深的謊言之一就是:
管理者只要懂管理就可以,不需要懂技術。
其實這不過是那些無知無能無恥的管理者為了騙錢而編出來的,相信這句話的人必將付出金錢的代價。
其 次是質量管理。基本的質量管理常識告訴我們,每次循環結束前,最重的工作就是總結改進。只有這樣才能保證循環運作是向上發展,而不是失去控制地向下發展。 也只有有效的質量管理,才能保證迭代過程是收斂發展,并最終達到目標。但在這個例子中,這個部分顯然是缺失的——其中雖然有測試部門,但是他們的作用僅僅 是質量管理中的質量檢測環節,管理部分還是缺失的。
然后是人力資源管理。軟件開發是一項勞動密集型的工作,雖然這是腦力勞動,但同樣意味著人在因素在其中占有決定性的地位。而例子中未改完BUG的程 序員拿到項目獎金,而同樣辛苦工作的測試人員卻被拖欠薪資,除了表現出管理者對他們的工作內容的不了解,以及對質量管理工作的不重視以外,還表現出管理者 完全不會管人,這是一種謀殺團隊的行為——謀殺一個團隊遠比建設要容易得多。
最后,這個失敗的管理者把他的經歷編成這個笑話,讓大家看到他被程序員們害得多慘,把程序員妖魔化為一群騙子。但只要稍懂管理的人簡單分析一下就可以看出來,只不過是這個人的無知和無能造成了他現在的結果,而把責任推給別人的行為更是表現出他的無恥。
作為身居高位的管理者,如果連應該承擔的責任都要推卸,他們還能勝任什么事情呢?
2006年5月8日
#
???? 百度公司今天搬到我們這幢樓內,更加刺激了我去百度的念頭,因為我喜歡創新的工作,所以我將為這一點而去努力奮斗。
???? 不是說百度公司有多好,主要是想穩定上幾年,有一點積蓄了,就可以自己出來自謀生路。呵呵。看見百度技術的職位只有無線搜索技術用到了JAVA,呵呵,不會灰心,其實,PYTHON或者RUR都將是以后的方向,至于PHP,我感覺百度會在不遠的將來拋棄掉的。在服務器的性能和安全爭端上我只相信JAVA,百度只不過把這一種技術很快轉化成了資本,如果百度想要和GOOGLE一爭高下,實質性的工作--技術上必須上要勝出GOOGLE一籌才行。而這一點只有行家才知道。
???? 我在北京的這幾年都是為代碼,或者就是為純粹的技術而奮斗,其實做為軟件公司,其起步主要是靠技術,但是他成名或者有所富裕后,就覺得人情是一個比技術還好玩的東西時,這個公司就開始有了差距,不過,這個公司就開始危險了,或者是窮途末路,只能鉆到錢眼里去了。如果管理層(其實就是和有權的腐敗工廠DANG有關系的人)沒有動靜的話,這個公司必死。這就是中國的國情。
? ?
???? 工廠DANG叫嚷的中國國情就是要隱含有權層的灰色收入,況且五千年的封建文化完全可以掩蓋這一點。否則,會把老祖宗也搬出來。孔子曰:孟子說:還有什么孫子談兵什么的。
?? ?
???? 從程序員的角度思索一下,如上是IF.....ELSE....的語句后,final,工廠DANG治理的天下亂七八糟。