いくつかのコード技術を共有する
いくつかのコード技術を共有する
Author : chenghao jun
説明
いくつかの私が知っているのを共有します.コード構造をより明確にするコード技術です.その中の多くの方法は私が他のソースプロジェクトのソースコードや本を読んで得た経験です.
私の例示的なコードは全部江湖の既存のバックボーンコードから来ています.もちろん、コード作者に関する情報は一切触れません.また、これらのコードは現実的な例から考えたもので、他の考えはありません.
私が述べた以下のテクニックはjavaのコードに限らず、いくつかの解決策を提供して、できるだけすべてのコードライフに適用します.
コーディングテクニック
衛説文を使う
卫述句は最も掌握しやすく、最大の効果を得る符号化技法の一つである.だから私はここでそれを第一位に並べます.
卫述句の最大の役割は、コードの深層的な入れ子を避けることです.コードの不要な深層ネストをもたらしやすいシーンは、if-elseネスト、for、while反復などがあります.したがって、その使用シーンの多くは判定ロジック(if文)と反復ロジック(for,while,etc)に存在する.
注意:卫叙句を使ったら、異常な流れが終わりました.プロセスを終了する場合は常にreturnとthrow文なので、衛述文を使うにはこの二つの文にもっと力を入れなければなりません.
模範的なタイプ
comple.taobao.matirix.friend.ap.web.home.module.actions.friend.FriendRelationAction.doUpdateFriendynamicSet
元のコード:
try {
int flag = rundata.getParameters().getInt("flag", -1);
String friendIds = null;
List<Long> friendsList = new ArrayList<Long>();
if (!friendsList.isEmpty()) {
Result result;
if (flag != -1) {
if (flag == 0) {//
// ...
} else if (flag == 1) {//
// ...
} else if (flag == 2) {//
// ...
}
}
}
} catch (Exception e) {
logger.error(e);
}
以上はFriendRelationAction.javaのコードの一部です.このコードは3つのネストされた語句を使用しています.よく見てください.この二つのif文(下線で表示する)は友好的ではありません.二つの判断ロジックは正常な論理を確定するためにコードに必要のない二つの段階の入れ子をもたらします.
改善の措置は、異常論理を確定し、異常論理を処理した後、returnまたはthrowを使って直接異常フローを終了することです.コードのネスト問題を解決します.このシーンでは、最適化されたコードは何の入れ子もありません.
最適化コード:
try {
int flag = rundata.getParameters().getInt("flag", -1);
String friendIds = null;
List<Long> friendsList = new ArrayList<Long>();
if (friendsList.isEmpty()) {
throw new IllegalStateException("friends is empty!");
}
if (flag == -1) {
return;
}
if (flag == 0) {//
// ...
} else if (flag == 1) {//
// ...
} else if (flag == 2) {//
// ...
}
} catch (Exception e) {
logger.error(e);
}
上記の説明と例を見て、下記のコードをどのように最適化するか分かりましたか?
comple.taobao.matirix.exchange.biz.service.impl.AwardHomeServiceImpl.queryMyAwardHome
// 3. ,
// , id
// , list
if (totalExpiredIdList != null) {
totalList.addAll(totalExpiredIdList);
if (totalList.size() > awardQuery.getPageSize()) {
// 1) ,
rntList.addAll(totalList.subList(0, awardQuery
.getPageSize()));
} else {
// 2)
rntList.addAll(totalList);
}
} else {
//
rntList.addAll(totalList);
反復中はcontinue,return,breakをフレキシブルに使う
私が学校に行って初めてc言語を勉強した時、その中の循環は私を最も悩ませた部分の一つです.特に反復中の++に対しては、操作符はめちゃくちゃです.今はもう学校に行く時の問題がありませんが、サイクルにぶつかるとやはり条件反射があります.循環中のコードを簡潔にすることができます.コードをよりよく理解できるようになります.
実はcontinue、return、breakの3つの文は基本的にどのプログラミング言語も持つ論理制御文であり、反復の中でこの3つの文を柔軟に使えば、良好なコントロールサイクルの中で入れ子と論理複雑度があります.
模範的なタイプ
元のコード:
comple.taobao.matirix.ac.service.SnsUserQueryServiceImpl.parse Terminators Resonse
for (DocumentDO doc : docs) {
List<FieldDO> fields = doc.getFields();
if (fields != null) {
QueryUserInfo user = new QueryUserInfo();
// other operates
userList.add(user);
}
}
other ここで私はいくつかのコードを省きました.現実のコードはこの方法の中に5層の入れ子があります.この醜いIF文を見て何をしましたか?本来ネストする必要がないコードブロックを彼の管轄範囲に加えました.
次に私は一つのcontinue文を使って彼を最適化します.入れ子したコードをリリースします.
最適化コード:
for (DocumentDO doc : docs) {
List<FieldDO> fields = doc.getFields();
if (fields == null || fields.size() == 0) {
continue;
}
QueryUserInfo user = new QueryUserInfo();
// other operates
userList.add(user);
}
一時変数はできるだけ匿名にします。
このコード技術は「魔力を発する大括弧」を使っていますが、私は初めて(ボブ) Leeを見ました.
私たちが仮定するシーンは単なる一時的な必要性にすぎない.一時的には、つまり一回操作した後、対象が圧倒的に多く廃棄されたシーンだと理解しています.例えば、セットにオブジェクトをパラメータとして読み込む場合などです.
この例を説明する前に、まず次のようなシーンを想定してみます.私たちはSnsUserオブジェクトが必要で、あるインターフェースがこのオブジェクトを必要とし、このオブジェクトの5つの属性、例えばuserId、realName、nickなどを使用します.
質問の意味を読んだら、この相手を作る方法は何ですか?
comp.taobao.matrix.uc.SnsUser
SnsUser u. = new SnsUser()u.setUserId(1 l)u.setNick(「nick」)u.set RealName(「realName」);method.invoke(u)
これもほとんどの人の対処方法だと信じています.しかし、私たちは濫用される危険を冒して、一時的な、あるいは余分なSnsUserの実例を守る必要があるでしょう.このオブジェクトが一時的であれば、より友好的な方法でこのオブジェクトを作成します.
下の表を見てください
method.invoke(new SnsUser() {{//
setUserId(1l);
setNick("nick");
setRealName("realName");
}});
このような処理は匿名クラスを実現する際によく使われる手段であり、私もxwork 2を読んでいます. injection コードの時、偶然に天才を発見したgoogleプログラマーが、このような新しい方式でオブジェクトを作成しました.私は初めて(ボブ) Leeを見ました.この方法を使います.
この方法は特にIbatisを使用する際に、Mapをパラメータとして導入する場合に適しています.
getDaoSupport().execute(new HashMap<String, String>() {
{
put("params1", "...");
put("params2", "...");
put("params3", "...");
put("params4", "...");
}
});
模範的なタイプ
comple.taobao.matirix.ac.service.SnsPlugine Center ServiceImpl.findPluginDataByUser
元のコード:
for (final PluginDataDO pd : list) {
res = new PluginData();
res.setId(pd.getId());
res.setUserId(pd.getUserId());
res.setPluginId(pd.getPluginId());
res.setTitle(pd.getTitle());
res.setIcon(pd.getIcon());
res.setGmtCreate(pd.getGmtCreate());
res.setGmtModified(pd.getGmtModified());
res.setIsDeleted(pd.getIsDeleted());
result.add(res);
}
PluginDataの例示的なresは反復中の一時的なオブジェクトにすぎず、resはこの反復の論理において完全に余分である.反復コードブロックの外で変数自体を説明するのも危険であり、これは本来反復内部でしか使用されない変数が他の濫用に便利である.
この臨時的な実例的な声明を抜きましょう.重複と濫用を避けます.
最適化コード:
for (final PluginDataDO pd : list) {
result.add(new PluginData() {{
setId(pd.getId());
setUserId(pd.getUserId());
setPluginId(pd.getPluginId());
setTitle(pd.getTitle());
setIcon(pd.getIcon());
setIcon(pd.getIcon());
setGmtCreate(pd.getGmtCreate());
setGmtModified(pd.getGmtModified());
setIsDeleted(pd.getIsDeleted());
}});
}
いくつかの感想
この文書を書き終えた時、私は突然笑い話があると思いました.経験豊富なベテラン医師が研究し、実戦豊富な医者が講演し、本を出します.
はい、私達の今の開発状況を説明するために修正しました.経験が豊富なベテランプログラマが構造を作ります.コードがとても優秀なプログラマはPM、TLをします.残りは実習プログラマコードのトレーナーだけです.