您好,登錄后才能下訂單哦!
本篇內容主要講解“優秀程序員都在注意的點有哪些”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“優秀程序員都在注意的點有哪些”吧!
很多事情并不難,只是缺乏多走半里路的習慣!
反例
public boolean isInValid(String str) { if (str == null || str.trim().length() == 0) { return true; } return false; }
多走一步,海闊天空
public boolean isInValid(String str) { return (str == null) || (str.trim().length() == 0); }
是個程序員都知道哪個更好!
還有一種見過很多次的代碼:
public boolean isEmptyName() { return StringUtils.isEmpty(name)? true: false; }
難道不感覺到多余嗎?
再走半步,山清水秀
public boolean isEmptyName() { return StringUtils.isEmpty(name); }
NullPointException,讓我們防不勝防;尤其是使用第三方API,如果拋出這個異常,會讓人有罵街的沖動。所以:若不想踩坑,請先別給別人挖坑。
理想要求:我們生產的所有public帶返回值的方法體中,不應該出現“return null”字樣。空對象就是這一思想的落地實現。
案例:查詢并返回一個名字為steven的老師或者學生。
public static SearchFilter name(String name) { return human -> human.getName().equalsIgnoreCase(name); } public Human find(SearchFilter filter) { for (Human human : humans) { if (filter.isMatched(human)) { return human; } } return new NullHuman(); //如果你返回NULL,總有一天你會挨罵! } //Test assertFalse(edu.find(name("steven")).isNull());
談起設計模式,很多人會覺得高大上,于是當學會了其中一個時,便會不加節制的使用。
單例,GOF中最簡單的一個設計模式,很好用、也非常方便,但說實話很多人在濫用。我們的系統中隨處可見,但用前請叩問自己該類真的是在系統當中有并且只能有一個實例嗎?
否則請拒絕單實例。太多的單實例會給你的自動化測試帶來無窮的煩惱。
枚舉有一些比較強大的特性容易被忽視,比如枚舉對象本身也可以攜帶變量;這一特性讓枚舉在更多的場合發揮不可替代的功用。
舉例:不同武器具有不同的殺傷力,殺傷力變量可以攜帶到武器的枚舉值中。
public enum EquipmentEnum { Staff(20), Hammer(10); double playerRisedAbility; EquipmentEnum(double playerRiseAbility) { this.playerRisedAbility = playerRiseAbility; } public double getRaiseAbility(double originalAbility) { return Double.sum(originalAbility, playerRisedAbility); } }
30%的代碼注釋比的時代已經成為過去,最好的注釋的就是無需注釋,程序員應該致力于通過命名讓注釋消失。
大量的實踐證明,隨著重構頻率越來越高,重構過程中隨著代碼的變更同步更新注釋的可能性幾乎為零。久而久之,注釋與代碼就是南轅北轍。
好的命名能夠愉悅讀者的心情,讓人有想一睹作者真面目的沖動!
案例:
一個房地產開發商一個新的樓盤開盤,原價80萬每套,有如下優惠策略,但優惠政策可能隨著樓盤存量情況會不一樣,為開發商寫一個房款計算程序
老客戶買二套房可優惠4%,可累加
一次性全款客戶可優惠3%,可累加
public class Customer { Benefiter benefit = new NullBenefiter(); public void is(Benefiter benefits) { //原本的set方法,重命名會帶來意想不到的效果。 this.benefit = benefits; } public double shouldPay(double srcPrice) { return srcPrice - benefit.benefit(srcPrice); } } @FunctionalInterface public interface Benefiter { abstract double benefit(double srcPrice); default Benefiter and(final Benefiter otherPolicy) { return srcPrice -> (benefit(srcPrice) + otherPolicy.benefit(srcPrice)); } }
受益于良好命名,客戶代碼語義躍然紙上:customer.is(oldCustomer().and(fullPay()));
數組是任何一門相對高級的機器語言的必備數據結構,但是對面向對象開發人員而言,似乎對它有所忽略。
在一些特定的場景下,它能起到意想不到的效果。
案例:美元、法郎、人民幣三幣種間換算。其中美元:法郎=1:2;美元:人民幣=1:8;
public class ExchangeRate { public static final int DOLLAR = 0; public static final int FRANC = 1; public static final int YMB = 2; private static final double[][] rates = { //二維數組定義幣種之間的匯率,簡單高效 {1.0d, 2.0d, 8.0d}, {0.5d, 1.0d, 4.0d}, {0.125d, 0.25d, 1.0d} }; public static double getRateOf(Currency src, Currency tgt) { return rates[src.ID][tgt.ID]; } } public class Cash { private double value; private Currency unit; public Cash(double value, Currency unit) { this.value = value; this.unit = unit; } @Override public boolean equals(Object obj) { if (obj instanceof Cash) { Cash other = (Cash) obj; return value == other.value * getRateOf(other.unit, unit); } return false; } }
如果匯率的二維數組使用配置文件定義并初始化,那還可以將設計提升一個新的高度——易于擴展,甚至不需修改任何Java代碼即可完成幣種的擴展。
當我們調用外部API時,最理想的就是零入參,即便有入參也希望是類型明確且范圍可枚舉的,這樣會讓我們使用這個API時更具安全感!心同此理,當你把一個函數聲明為public時,請謹慎地定義它的入參。
如果把上述案例中獲取兩種幣種之間的匯率函數:
public static double getRateOf(Currency src, Currency tgt) { return rates[src.ID][tgt.ID]; }
定義為
public static double getRateOf(int src, int tgt) { return rates[src][tgt]; }
雖然函數實現簡單了一些,但可想而知,這個API會讓使用者很忌憚!數組越界異常肯定是經常發生。
相反通過枚舉規約了入參的類型和范圍,給用戶一些固定選項,使用者少了很多顧慮,而我們的程序也更加安全。
所以:我們對外提供的API入參類型盡量少用String、Int這種基本類型,給使用者發揮的空間越大,犯錯的可能越大,因為你把風險暴露在不受控的用戶手里。
你是否為反復地編寫類似“if (tasks != null && tasks.size() > 0)”或者“if (name != null && (!name.isEmpty()))”的代碼而心浮氣躁,其實你完全可以解救自己。
封裝一下
public class CollectionUtil { public static boolean isEmpty(Collection collection) { return collection == null || collection.isEmpty(); } }
以及
public class StringUtil { public static boolean isEmpty(String context) { return context == null || context.isEmpty(); } }
一切變得非常簡單,心情好了,效率也就高了!
我們的系統充斥著if/else的邏輯,因為它邏輯“簡單”、易用!但隨著時間推移、需求的擴展,有一天你會發現自己都看不懂自己寫的if/else。
所以一開始就要學會拒絕這種邏輯的嵌套,又或者是當你看嵌套的復雜邏輯,大膽的對它進行重構。
案例:輸入一個1-1000的數值N,如果N是3或者3的倍數時,返回“FIZZ”;如果N是5或者5的倍數時, 返回“BUZZ”;既是3的倍數又是5的倍數時, 返回“FIZZBUZZ”;其他的則輸出N。
public String say(int input) throws Exception { if ( input < 1 || input > 1000){ throw new Exception("Invalid input"); } if (input % 15 == 0) { return "FIZZBUZZ"; } if (input % 5 == 0) { return "BUZZ"; } if (input % 3 == 0) { return "FIZZ"; } return String.valueOf(input); }
嗅一嗅其中的壞味道,如果將來需求擴展,比如引進7的倍數。照此邏輯,繼續添加if,問題是解決了,但總有一天你會懷疑人生!
public String say(int input) throws Exception { if (input < 1 || input > 1000) { throw new Exception("Invalid input"); } DefaultParser defaultParser = new DefaultParser(null); MultiOfThreeParser multiOfThreeParser = new MultiOfThreeParser(defaultParser); MultiOfFiveParser multiFiveParser = new MultiOfFiveParser(multiOfThreeParser); MultiOfFifteenParser fifteenPaser = new MultiOfFifteenParser(multiFiveParser); return fifteenPaser.parse(input); } public abstract class Parser { abstract boolean isFixedResponsibility(int inputContext); abstract String response(int inputContext) throws Exception; public String parse(int inputContext) throws Exception { if (isFixedResponsibility(inputContext)) { return response(inputContext); } if (nextParser != null) { return nextParser.parse(inputContext); } return NULL; } } public class MultiOfFifteenParser extends Parser { public MultiOfFifteenParser(Parser nextParser) { super(nextParser); } @Override public String response(int inputContext) throws Exception { return FLAG_FOR_MULIT_OF_FIFTEEN; } @Override boolean isFixedResponsibility(int inputContext) { return inputContext % 15 == 0; } }
看起來好多了,但感覺好像還有哪兒不太對勁!
敏銳的讀者可能還會發現上述改進還存在細微的小問題,那就是say方法里面的異常分支處理。怎么還存在一個if,對于一個完美主義強迫癥患者而言,它的存在就是一個災難。繼續改進一下:
public String say(int input) throws Exception { DefaultParser defaultParser = new DefaultParser(null); MultiOfThreeParser multiOfThreeParser = new MultiOfThreeParser(defaultParser); MultiOfFiveParser multiOfFiveParser = new MultiOfFiveParser(multiOfThreeParser); MultiOfFifteenParser FifteenPaser = new MultiOfFifteenParser(multiOfFiveParser); InvalidNumberParser invalidNumberPaser = new InvalidNumberParser(FifteenPaser); return invalidNumberPaser.parse(input); } public class InvalidNumberParser extends Parser { public InvalidNumberParser(Parser nextParser) { super(nextParser); } @Override String response(int inputContext) throws Exception { throw new Exception("Invalid input"); } @Override boolean isFixedResponsibility(int inputContext){ return (inputContext < L_THRESHOLD) || (inputContext > H_THRESHOLD); } }
到此,相信大家對“優秀程序員都在注意的點有哪些”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。