日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

使您的Java代码闻起来很新鲜

發(fā)布時間:2023/11/29 java 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使您的Java代码闻起来很新鲜 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

by Marco Massenzio

由Marco Massenzio

使您的Java代碼聞起來很新鮮 (Make your Java code smell nice and fresh)

A few years ago I joined a startup working on a cloud enterprise service that was originally built by an offshore team.

幾年前,我加入了一家從事云企業(yè)服務(wù)的初創(chuàng)公司,該服務(wù)最初是由離岸團(tuán)隊構(gòu)建的。

The chosen technologies (REST, Java, MongoDB) were actually valid technical choices for the problem at hand. Too bad they then proceeded to get it spectacularly wrong with a bloated (and unmanageable) data schema and an even worse Java implementation.

所選技術(shù)(REST,Java,MongoDB)實際上是解決當(dāng)前問題的有效技術(shù)選擇。 不幸的是,他們隨后使用with腫的(且難以管理的)數(shù)據(jù)模式和更糟糕的Java實現(xiàn),將其改錯了。

The most amusing part was they genuinely believed that Mongo’s “schema-less” claim meant that there was no need for carefully designing the data model, thinking through the indexes, and considering how data would be accessed.

最有趣的部分是他們真正相信Mongo的“無架構(gòu)”主張意味著,無需仔細(xì)設(shè)計數(shù)據(jù)模型,仔細(xì)研究索引并考慮如何訪問數(shù)據(jù)。

In this post, I’d like to dissect the many “smells” (see Martin Fowler’s book) that a particular Java class was emitting, how this could have been avoided, and the many anti-patterns encountered.

在本文中,我想剖析特定Java類發(fā)出的許多“氣味”(請參閱??Martin Fowler的書 ),如何避免這種情況以及遇到的許多反模式。

My hope is that by reading this post, you will avoid making the same mistakes, and folks like me will not be required to come over and fix your stinkin’ code!

我希望通過閱讀這篇文章,您將避免犯同樣的錯誤,并且不需要像我這樣的人來解決您的臭代碼!

第一聞:沒有風(fēng)格 (First smell: no style)

I have previously ranted about the need to follow adequate (and widely accepted) code styles. In short:

之前,我曾抱怨需要遵循適當(dāng)?shù)?并被廣泛接受的)代碼樣式。 簡而言之:

  • New developers joining the team will have a less steep learning curve.

    加入團(tuán)隊的新開發(fā)人員的學(xué)習(xí)曲線不會那么陡峭。
  • Automated tools will be better able to provide insights.

    自動化工具將能夠更好地提供見解。
  • Trivial, avoidable bugs will be easy to spot.

    瑣碎的,可避免的錯誤將很容易發(fā)現(xiàn)。

And, yes, your code will look nicer and your self-respect will improve too. It’s hard to convince people of your brilliant insights when your code looks like you wrote it by bashing a caveman club against your keyboard.

而且,是的,您的代碼將看起來更好,并且您的自尊心也將得到改善。 當(dāng)您的代碼看起來像您編寫代碼時,通過打擊鍵盤上的穴居人俱樂部,很難讓人相信您的出色見解。

Here are some of the hallmarks of the “keyboard caveman”:

以下是“鍵盤穴居人”的一些標(biāo)志:

  • inconsistent use of spaces (sometimes before, sometimes after parentheses and around operators, or none at all)

    空格的使用不一致(有時在括號前,有時在括號后,運(yùn)算符前后,或者根本沒有)
  • inconsistent use of blank lines: sometimes one at random, sometimes two or more, then none

    空行使用不一致:有時是隨機(jī)的,有時是兩個或更多,然后是無
  • no regard for line-length (many lines longer than 100 columns, several longer than 200, and a 257 column record-breaking line)

    不考慮行長(許多行超過100列,幾行超過200列,以及257列打破記錄的行)
  • no use of Java 7's “diamond pattern” and some random uses of raw collections

    不使用Java 7的“鉆石圖案”,并且隨機(jī)使用原始集合

  • variable names that have little to do with their true meaning

    變量名與其真實含義無關(guān)
  • inconsistent use of constants and hard-coded strings — sometimes the same hard-coded string repeated several times within a few lines of code — clearly the result of copy-and-paste

    常量和硬編碼字符串的用法不一致-有時同一硬編碼字符串在幾行代碼中重復(fù)多次-顯然是復(fù)制粘貼的結(jié)果

and on and on…

還有……

Here are some tips for fixing your code style code smells:

以下是一些修復(fù)代碼樣式代碼氣味的提示:

  • Pick a good, widely know style guide and stick to it. Even better, have your IDE automatically enforce the coding style (both Eclipse and IntelliJ are very good at this).

    選擇一個好的,廣為人知的風(fēng)格指南并堅持下去。 更好的是,讓您的IDE自動執(zhí)行編碼樣式(Eclipse和IntelliJ在這方面都非常擅長)。

  • If your programming language of choice supports it, consider using an automated tool to find out code style infractions (such as pylint, jslint). Even better, make style checks part of your automated CI builds (and prevent commits until those pass).

    如果您選擇的編程語言支持,請考慮使用自動化工具找出違反代碼風(fēng)格的行為(例如pylint,jslint)。 更好的是, 將樣式檢查作為自動化CI構(gòu)建的一部分 (并在提交通過之前阻止提交)。

  • Be consistent in the use of spaces, blank lines, and line length. You never know when a project-wide, regex-driven search-and-replace will be necessary.

    在使用空格,空白行和行長時要保持一致 。 您永遠(yuǎn)不會知道何時需要在項目范圍內(nèi),由正則表達(dá)式驅(qū)動的搜索和替換。

  • Never use raw collections. Java generics are here for a reason. This one single point would deserve a post all of its own. I will get round to it in due course. In the meantime, please read Bloch’s excellent Effective Java.

    切勿使用原始集合。 Java泛型在這里是有原因的。 這一點(diǎn)很值得擁有。 我會在適當(dāng)?shù)臅r候解決它。 同時,請閱讀Bloch的出色的Effective Java 。

  • Spare a thought for the poor soul who’ll have to fix your stinkin’ code. It may even be you in a few months’ time!

    為需要修復(fù)您的臭味代碼的可憐靈魂保留思想。 幾個月后甚至可能是

第二聞:無法測試的代碼 (Second smell: untestable code)

I can’t tell you how many times I swore my code was bug-free, but wrote unit tests anyway. This has saved my butt so many times that it’s not even funny.

我無法告訴您我發(fā)誓我的代碼沒有錯誤的次數(shù),但是無論如何都編寫了單元測試。 這已經(jīng)救了我很多次,甚至都不好笑。

People, do unit test your code. Just do it.

人們,對您的代碼進(jìn)行單元測試。 去做就對了。

For starters, if you want your code to be tested, your code should be, well, testable.

對于初學(xué)者來說,如果您希望對代碼進(jìn)行測試,那么您的代碼應(yīng)該是可測試的。

Here’s an example of what not to do: a class was implemented to serve a particular API call which — in response to a client query — would serve a very complex object, with deeply nested sub-objects, all couched in a mix of business logic and UI-related data.

這是一個不執(zhí)行操作的示例:實現(xiàn)了一個類以服務(wù)于特定的API調(diào)用,該類調(diào)用(響應(yīng)于客戶端查詢)將為非常復(fù)雜的對象提供服務(wù),并帶有深度嵌套的子對象,這些子對象都包含在業(yè)務(wù)邏輯中以及與UI相關(guān)的數(shù)據(jù)。

When serving such a complex object back, you would want to test it under several different scenarios and ensure that the returned object conforms to the API documented specs.

向后提供這種復(fù)雜的對象時,您需要在幾種不同的情況下對其進(jìn)行測試,并確保返回的對象符合API 記錄的規(guī)范。

Except in this particular real-life case, there was virtually no documented API. In fact, not only there was also no unit testing, but the class was (and probably still remains) untestable.

除了在這種特殊的現(xiàn)實情況下,幾乎沒有文檔化的API。 實際上,不僅沒有單元測試,而且該類是(并且可能仍然)不可測試的。

What do I mean by this? well, take a look at this method:

我是什么意思 好吧,看看這個方法:

public static Map<String, Object> getSomeView( Map<String, Object> queryParams) { List<Map<String,Object>> results = SomeSearch.find(queryParams); ...}

As you can see, this method (which returns a Map whose values are Objects — just one step above being untyped) is static — as is the very first method called, which will eventually execute the query against MongoDB.

如您所見,此方法(返回一個Map,其值為Objects -僅在未類型化的步驟之上)是靜態(tài)的 - 第一個方法稱為靜態(tài) 方法 ,該方法最終將對MongoDB執(zhí)行查詢。

This makes it very difficult to mock the call, or the database query, or to construct a set of data-driven tests, which would have enabled us to test the data transformation and view generation logic in the method under several different scenarios.

這使得模擬調(diào)用,數(shù)據(jù)庫查詢或構(gòu)造一組數(shù)據(jù)驅(qū)動的測試變得非常困難,這使我們能夠在幾種不同的情況下測試方法中的數(shù)據(jù)轉(zhuǎn)換和視圖生成邏輯。

There is today PowerMockito that can solve some of these issues, but doing so is extremely laborious and error-prone. In my experience, mocking static methods requires a ratio of 10:1 lines of mocking code to actual test code.

今天有PowerMockito可以解決其中的一些問題,但是這樣做非常費(fèi)力且容易出錯。 以我的經(jīng)驗,模擬靜態(tài)方法需要模擬代碼與實際測試代碼的比率為10:1。

It’s also worth noting that queryParams could be pretty much anything. In this case, it’s a paging/sorting set of options. The only way you could have found that out, though, would be to run the actual server in debug mode, then execute the API call from a client and see what comes up at the other end.

還值得注意的是queryParams幾乎可以是任何東西。 在這種情況下,它是一組分頁/排序選項。 但是,您可能發(fā)現(xiàn)的唯一方法是在調(diào)試模式下運(yùn)行實際的服務(wù)器,然后從客戶端執(zhí)行API調(diào)用,然后查看另一端發(fā)生的情況。

Because, yes, you guessed it: there was absolutely no javadoc to explain what the method does.

因為,是的,您猜對了:絕對沒有javadoc可以解釋該方法的作用。

Consider, instead, if you’d had code similar to this:

考慮一下,如果您有類似以下的代碼:

@InjectQueryAdapter query;...public Map<String, ?> getSomeView(boolean sort, int skip, int limit) { List<Map<String,?>> results = query.find(sort, skip, limit); ...

For a start, you can mock the query object and return whatever you want during a test run. Secondly, it’s clear what the various parameters are from their names. This also limits the possible permutations that need to be tested. For example: if sort is true, are the returned results sorted? If limit is 1, do you actually get only one result? And so on.

首先,您可以模擬查詢對象并在測試運(yùn)行期間返回所需的任何內(nèi)容。 其次,很明顯,各種參數(shù)的名稱是什么。 這也限制了需要測試的可能排列。 例如:如果sort為true ,返回的結(jié)果是否排序? 如果限制為1,您實際上只得到一個結(jié)果嗎? 等等。

But most importantly, because none of the methods invoked is static, it is much easier to construct a test context that is easy to reason about.

但最重要的是,由于調(diào)用的方法都不是靜態(tài)的,因此構(gòu)造易于推理的測試上下文要容易得多。

Finally, if QueryAdapter were a Java interface, you can swap different implementations at runtime (perhaps driven by configuration), and still the code using and testing it remains perfectly valid.

最后,如果QueryAdapter是Java接口,則可以在運(yùn)行時交換不同的實現(xiàn)(可能由配置驅(qū)動),并且使用和測試它的代碼仍然完全有效。

外賣 (Takeaways)

  • use dependency injection (DI) wherever possible. Spring or Guice are really valid frameworks, and are critical in keeping your code clean, responsive to change and testable.

    盡可能使用依賴項注入 (DI)。 Spring或Guice是真正有效的框架,對于保持代碼的清潔,對更改的響應(yīng)和可測試性至關(guān)重要。

  • avoid, wherever possible, static methods, unless you absolutely have to. They make your code difficult to test, and really difficult to mock out. They also make your clients (the code that will use your classes/methods) extremely brittle, and equally untestable.

    除非絕對必要 ,否則應(yīng)盡可能避免使用靜態(tài)方法 它們使您的代碼難以測試,并且真的很難被模擬出來。 它們還會使您的客戶(使用您的類/方法的代碼)非常脆弱,并且同樣無法測試。

  • Java is a strongly typed language. There is a good reason for this. Let the compiler and the JVM do the legwork, and catch your (and others’) mistakes.

    Java是一種強(qiáng)類型語言。 這是有充分的理由的。 讓編譯器和JVM進(jìn)行繁瑣的工作,并捕獲您(和其他人)的錯誤。
  • Avoid using String and Object everywhere as a poor man’s dynamic language. If you really cannot devise a data object model for your business entities, you should actually consider a true dynamic language (Python being an excellent choice).

    避免到處使用String和Object作為窮人的動態(tài)語言。 如果您確實無法為您的業(yè)務(wù)實體設(shè)計數(shù)據(jù)對象模型,那么您實際上應(yīng)該考慮使用一種真正的動態(tài)語言 (Python是絕佳的選擇)。

  • Document your code. Make sure all public methods have an adequate javadoc for others to understand and use. Also ensure that your classes’ javadoc explains clearly what the class does, how to use it, and also examples of correct (and, potentially, incorrect too) usage. And, most importantly, document you APIs, what the method expects to receive, and what they’re supposed to return.

    記錄您的代碼。 確保所有公共方法都有足夠的javadoc供其他人理解和使用。 還要確保您的類的javadoc清楚地說明了該類的用途,用法以及正確(甚至可能不正確)用法的示例。 而且,最重要的是,記錄您的API,該方法預(yù)期接收的內(nèi)容以及它們應(yīng)返回的內(nèi)容。

This last point is particularly important: use your unit tests also as a means of demonstrating how your code’s API should be used (and how it shouldn’t be used).

最后一點(diǎn)特別重要:使用單元測試還可以說明如何使用代碼的API(以及不應(yīng)使用的API)。

第三氣味:令人困惑的代碼 (Third smell: confusing code)

It took me the best part of an hour to reverse-engineer the following method. Then I passed it on to my colleagues as a “Java Puzzler” and their guesses were wildly confused, too.

我花了一個小時的大部分時間來對以下方法進(jìn)行反向工程。 然后,我將其作為“ Java Puzzler”傳遞給了我的同事,他們的猜測也大為困惑。

I have “obfuscated” some of the code to preserve confidentiality and avoid embarrassment, but trust me, the obfuscation does make this version less obscure than the original:

我有“混淆”的一些代碼,以保持機(jī)密性,避免尷尬,但相信我, 混淆確實讓這個版本模糊比原來:

// Much as it pains me, I've left the code style (or lack thereof) untouched// PLEASE DON'T DO THIS AT HOMEprivate static String getSomething(boolean isOnRoute, List<Map<String,Object>> trip, String primarySomething, String id){ boolean somethingKnown = isOnRoute; if(!somethingKnown && trip!=null){ for(Map<String,Object> segment: trip){ Map<String,Object> line = (Map<String, Object>) thisLeg.get(Constants.LINE); if(line!=null){ String something = (String) carrierLane.get(Constants.SOMETHING); LOG.debug("Line something: "+something); if(primarySomething.equals(something)){ somethingKnown = true; break; } } } } if(somethingKnown){ return primarySomething; } LOG.debug("Unknown something:: isOnRoute:'" + isOnRoute + "' ; primarySomething:'" + primarySomething + "' ; id:'" + id + "'"); return null;}

Taking you out of your misery, all this method does is to return the value (primarySomething) that was originally given to it if the trip isOnRoute. If not, it will tell you so, then return null — and let us gloss for a moment on the fact that it requires the caller to pass in the id only to use it in a debug statement.

如果您的旅程是onRoute ,那么使您擺脫苦難的所有方法都是返回最初賦予它的值( primarySomething ) 。 如果不是,它將告訴您,然后返回null-讓我們暫時了解一下,它要求調(diào)用者僅在調(diào)試語句中使用id時才傳遞id 。

Also, note the unnecessary use of a boolean variable (somethingKnown) only to use it in the break case, and then fall into a return statement. And there are so many other issues here. For example, why assign the value of a flag that indicates whether the trip is “on route” to a flag that indicates whether that elusive something was found?

另外,請注意不必要只使用布爾變量( somethingKnown )才能在break情況下使用它,然后落入return語句中。 這里還有很多其他問題。 例如,為什么將指示旅行是否“在途中”的標(biāo)志的值分配給指示是否找到了難以捉摸的東西的標(biāo)志?

In the end, we figured out that this method was entirely pointless, and we removed it entirely.

最后,我們發(fā)現(xiàn)此方法完全沒有意義,因此我們將其完全刪除。

Sad as it sounds, hitting the DEL key on that pile of crap was the high point of my day.

聽起來很傷心,敲那堆廢話的DEL鍵是我今天的重點(diǎn)。

Here are some tips for avoiding confusing code:

以下是一些避免混淆代碼的技巧:

  • Try and make the intent of your method(s) obviously clear to the readers of your code. Follow agreed-upon naming conventions, clear arguments lists, clear algorithm implementations, and help your co-workers do the same.

    嘗試使您的方法的意圖對您的代碼讀者顯而易見。 遵循商定的命名約定,清除參數(shù)列表,清除算法實現(xiàn),并幫助您的同事進(jìn)行相同的操作。
  • Even doing that, always add a Javadoc to explain what the intent is, what the arguments are supposed to be, and what the expected outcome should be (including possible side-effects).

    即使這樣做,也總是添加一個Javadoc來解釋意圖是什么,參數(shù)應(yīng)該是什么,以及預(yù)期的結(jié)果是什么(包括可能的副作用)。

  • Avoid shortcuts that will render the logic of your code obscure to other developers.

    避免使用會使其他開發(fā)人員難以理解代碼邏輯的快捷方式。
  • And, for God’s sake, avoid concatenating strings. The String.format() and slf4j string composition pattern are there for a reason:

    而且,看在上帝的份上,避免串聯(lián)字符串。 出現(xiàn)String.format()和slf4j字符串組成模式是有原因的:

// Log4J:LOG.debug(String.format(“The result is: %d”, result));// logback or slf4j: this is more desirable, as you won't incur// the cost of building the string, unless the log level// will actually cause the log message to be emittedLOG.error(“The gizmo [{}] was in {}, but then fritzed at {}, {}”, gizmoId, state, foo, bar)

第四味:復(fù)制并粘貼代碼 (Fourth smell: Copy & pasted code)

You remember when you were a kid and you were asked to “spot the difference” between two pictures that seemed identical? Let’s play the opposite game. Can you spot the similarities?

您還記得您小時候被問到“發(fā)現(xiàn)兩幅看上去相同的照片之間的差異”嗎? 讓我們玩相反的游戲。 您能發(fā)現(xiàn)相似之處嗎?

// Again, I've left the code style (or lack thereof) untouched// PLEASE DON'T DO THIS AT HOMEList<Map<String, Object>> originSiteEvents = null;List<Map<String, Object>> destinationSiteEvents = null;List<Map<String, Object>> inventoryEvents = null;try{ originSiteEvents = (List<Map<String, Object>>) ((Map<String, Object>) ((Map)entry.get(ModelConstants.INVENTORY)).get(ModelConstants.ORIGIN)).get(ModelConstants.EVENTS);} catch (Exception e){ //No origin events avaislable}try{ inventoryEvents = (List<Map<String, Object>>) ((Map)entry.get(ModelConstants.INVENTORY)).get(ModelConstants.EVENTS);} catch (Exception e){ //No inventory events available}try{ destinationSiteEvents = (List<Map<String, Object>>) ((Map<String, Object>) ((Map)entry.get(ModelConstants.INVENTORY)).get(ModelConstants.DESTINATION)).get(ModelConstants.EVENTS);} catch (Exception e){ //No destination events available}if(events != null){ List<Map<String, Object>> eventListForLeg = (List<Map<String, Object>>) events; for(int j=eventListForLeg.size()-1; j>=0; j--){ Map<String, Object> event = eventListForLeg.get(j); if(event.get("category")!=null && event.get("category").equals("GPS")){ event.put("isLastGPSEvent", true); break; } }}if(destinationSiteEvents != null){ for(int j=destinationSiteEvents.size()-1; j>=0; j--){ Map<String, Object> event = destinationSiteEvents.get(j); if(event.get("category")!=null && event.get("category").equals("GPS")){ event.put("isLastGPSEvent", true); return; } }}if(inventoryEvents != null){ for(int j=inventoryEvents.size()-1; j>=0; j--){ Map<String, Object> event = inventoryEvents.get(j); if(event.get("category")!=null && event.get("category").equals("GPS")){ event.put("isLastGPSEvent", true); return; } }}if(originSiteEvents != null){ for(int j=originSiteEvents.size()-1; j>=0; j--){ Map<String, Object> event = originSiteEvents.get(j); if(event.get("category")!=null && event.get("category").equals("GPS")){ event.put("isLastGPSEvent", true); return; } }}

As you are probably aware, copy & pasting code is a blatant violation of the DRY principle (“Don’t Repeat Yourself”). Not to mention, it’s pretty awful to look at. It will also make you look like a lazy chump to anyone who knows the first thing about software development.

您可能已經(jīng)知道,復(fù)制和粘貼代碼公然違反了DRY原則(“不要重復(fù)自己”)。 更不用說,它看起來很糟糕。 對于任何了解軟件開發(fā)的第一手知識的人,它也會讓您看起來像個懶惰的家伙。

It’s worth mentioning that the same exact pattern (navigating nested maps according to sequence of strings) was scattered all over the 600+ lines of code of this class. So, you’d be forgiven for coming up with a utility method like the one I hacked together in less than 10 minutes to replace the abomination above:

值得一提的是,同一類完全相同的模式(根據(jù)字符串序列導(dǎo)航嵌套映射)分散在此類的600多行代碼中。 因此,您提出了一種實用程序方法,例如我在不到10分鐘的時間內(nèi)就砍掉了上面的可憎性的一種實用程序方法,這是可以原諒的:

/** * Navigates the {@literal path} in the given map and tries * to retrieve the value as a list of objects. * * <p>This is safe to use, whether the path exists or not, * and relatively safe against {@link java.lang.ClassCastException} * errors (to the extent that this kind of code can be). * * @param map the tree-like JSON * @param path the path to the desired object * @return the list of objects, or {@literal null} if any of the * segments does not exist */@SuppressWarnings("unchecked")public static List<Map<String, ?>> tryPath( Map<String, ?> map, List<String> path) { List<Map<String, ?>> result = null; Map<String, ?> intermediateNode = map; String tail = path.remove(path.size() - 1); for (String node : path) { if (intermediateNode.containsKey(node)) { Object o = intermediateNode.get(node); if (o instanceof Map) { intermediateNode = (Map<String, ?>) o; } else { LOG.error("Intermediate node {} cannot be " + "converted to a Map ({})", node, o); return null; } } else { return null; } } if (intermediateNode.containsKey(tail)) { Object maybeList = intermediateNode.get(tail); if (maybeList instanceof List) { return (List<Map<String, ?>>) maybeList; } } return null;}

The result is that the sequence of lookups (which, again, when first encountered looked like a riddle wrapped in an enigma) now looks something like:

結(jié)果是查找的順序(再次遇到時,看起來就像是一個被謎團(tuán)包裹的謎語)現(xiàn)在看起來像:

List<List<String>> paths = Lists.newArrayList();paths.add(Lists.newArrayList(Lists.asList( ModelConstants.INVENTORY, new String[] { ModelConstants.EVENTS})));paths.add(Lists.newArrayList(Lists.asList( ModelConstants.INVENTORY, new String[] { ModelConstants.ORIGIN, ModelConstants.EVENTS})));paths.add(Lists.newArrayList(Lists.asList( ModelConstants.INVENTORY, new String[] { ModelConstants.DESTINATION, ModelConstants.EVENTS})));List<Map<String, ?>> events = null;for (List<String> path : paths) { events = tryPath(entry, path); if (events != null) { break; }}if (events != null) { for (int j = events.size() - 1; j >= 0; --j) { Map<String, Object> event = (Map<String, Object>) events.get(j); if (event.contains("category") && Constants.GPS.equals(event.get("category"))) { event.put(Constants.isLastGPSEvent, true); return; } }}

This is still not as clean as I’d like it to be, but I mostly blame Java for lacking a factory class similar to Scala’s Lists:

這仍然不像我希望的那樣干凈,但是我主要?dú)w咎于Java缺少類似于Scala的Lists的工廠類:

val paths = List(List(ModelConstants.INVENTORY, ModelConstants.EVENTS, List(ModelConstants.INVENTORY, ModelConstants.ORIGIN, ModelConstants.EVENTS), List(ModelConstants.INVENTORY, ModelConstants.DESTINATION, ModelConstants.EVENTS))

Also a quick note the anti-pattern of using a try-catch block to filter out potentially valid code paths, and avoiding writing null and key-existence checks.

還要快速注意一下使用try-catch塊來過濾出可能有效的代碼路徑并避免編寫空值和鍵存在檢查的反模式。

By factoring out the checks and the class casts (with proper type safety checks) in one place, you avoid having to choose between two bad options, which are: scatter the same repetitive, tedious checks all over the place, or mask out possible error codes by casting a very wide net.

通過將檢查和類強(qiáng)制轉(zhuǎn)換(帶有適當(dāng)?shù)念愋桶踩珯z查)分解為一個地方,您可以避免在兩個錯誤的選項之間進(jìn)行選擇,這些錯誤的選項是:在整個地方分散相同的重復(fù),乏味的檢查,或者掩蓋可能的錯誤通過投射非常寬的網(wǎng)絡(luò)進(jìn)行編碼。

If you let through potentially erroneous conditions, you will make it exceedingly difficult to find out root causes of unexpected bugs.

如果您讓潛在的錯誤條件經(jīng)受了考驗,那么將很難找出意外錯誤的根本原因。

There’s an entire blog post to be written about “swallowing” exceptions and error conditions.

有整篇博客文章要寫,涉及“吞咽”異常和錯誤條件。

So:

所以:

  • don’t copy & paste code: if you see commonality, factor out the common parts and re-use them (in a utility class or a helper method);

    不要復(fù)制和粘貼代碼 :如果您看到通用性,請分解出通用部分并重新使用它們(在實用程序類或幫助器方法中);

  • don’t avoid safety checks in your code by indiscriminately “swallowing” exceptions: try-catch blocks should be there for a reason, and the reason should be (the giveaway being in the name) exceptional.

    不要通過隨意地“吞咽”異常來避免代碼中的安全檢查: try-catch塊應(yīng)該是有原因的,而原因應(yīng)該是(贈品是特例 ) 異常 。

Code is still largely a craft. A deep understanding of issues related to distributed computing, a capacity for critical reasoning and abstract thinking, and an understanding of operational issues related to scalable systems — these are critical these days for becoming a great software developer. Still, the mastery of the craft is as important as it was in Renaissance Italy.

代碼在很大程度上仍然是一種技巧 。 對與分布式計算有關(guān)的問題的深刻理解,對關(guān)鍵推理和抽象思維的能力以及對與可伸縮系統(tǒng)有關(guān)的操作問題的理解,這些對于如今成為一名出色的軟件開發(fā)人員而言至關(guān)重要。 盡管如此,對手藝的掌握與意大利文藝復(fù)興時期一樣重要。

Write well-designed, clearly structured and properly documented code — and be proud of your craft!

編寫設(shè)計良好,結(jié)構(gòu)清晰且文檔正確的代碼,并為您的手藝感到驕傲!

And if you want to make fun of my code, just head to my github repositories, I’m sure there’s still plenty of smells there (but, hopefully, also a few nuggets of good code that will hopefully inspire you!)

而且,如果您想取笑我的代碼,只需轉(zhuǎn)到我的github存儲庫 ,我肯定那里仍然有很多氣味(但是,希望還有一些好的代碼能夠激發(fā)您的靈感!)

Originally published at codetrips.com on January 25, 2015.

最初于2015年1月25日發(fā)布在codetrips.com 。

翻譯自: https://www.freecodecamp.org/news/do-not-allow-bad-smells-in-your-java-code-4e8ad244393/

總結(jié)

以上是生活随笔為你收集整理的使您的Java代码闻起来很新鲜的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。