最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java優(yōu)化重復(fù)冗余代碼的8種方式總結(jié)

 更新時間:2023年08月23日 08:24:43   作者:撿田螺的小男孩  
日常開發(fā)中,我們經(jīng)常會遇到一些重復(fù)代碼,最近小編優(yōu)化了一些系統(tǒng)中的重復(fù)代碼,用了好幾種的方式,感覺挺有用的,所以本文給大家講講優(yōu)化重復(fù)代碼的幾種方式

1. 抽取公用方法

抽取公用方法,是最常用的代碼去重方法~

比如這個例子,分別遍歷names列表,然后各自轉(zhuǎn)化為大寫和小寫打印出來:

public class TianLuoExample {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David", "TianLuo");
        System.out.println("Uppercase Names:");
        for (String name : names) {
            String uppercaseName = name.toUpperCase();
            System.out.println(uppercaseName);
        }
        System.out.println("Lowercase Names:");
        for (String name : names) {
            String lowercaseName = name.toLowerCase();
            System.out.println(lowercaseName);
        }
    }
}

顯然,都是遍歷names過程,代碼是重復(fù)的,只不過轉(zhuǎn)化大小寫不一樣。我們可以抽個公用方法processNames,優(yōu)化成這樣:

public class TianLuoExample {
    public static void processNames(List<String> names, Function<String, String> nameProcessor, String processType) {
        System.out.println(processType + " Names:");
        for (String name : names) {
            String processedName = nameProcessor.apply(name);
            System.out.println(processedName);
        }
    }
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David", "TianLuo");
        processNames(names, String::toUpperCase, "Uppercase");
        processNames(names, String::toLowerCase, "Lowercase");
    }
}

2. 抽工具類

我們優(yōu)化重復(fù)代碼,抽一個公用方法后,如果發(fā)現(xiàn)這個方法有更多共性,就可以把公用方法升級為一個工具類。比如這樣的業(yè)務(wù)場景:我們注冊的時候,修改郵箱,重置密碼等,都需要校驗郵箱

實現(xiàn)注冊功能時,用戶會填郵箱,需要驗證郵箱格式,

public class RegisterServiceImpl implements RegisterService{
    private static final String EMAIL_REGEX =
        "^[A-Za-z0-9+_.-]+@(.+)$";
    public boolean registerUser(UserInfoReq userInfo) {
        String email = userInfo.getEmail();
        Pattern pattern = Pattern.compile(EMAIL_REGEX);
        Matcher emailMatcher = pattern.matcher(email);
        if (!emailMatcher.matches()) {
            System.out.println("Invalid email address.");
            return false;
        }
        // 進(jìn)行其他用戶注冊邏輯,比如保存用戶信息到數(shù)據(jù)庫等
        // 返回注冊結(jié)果
        return true;
    }
}

密碼重置流程中,通常會向用戶提供一個鏈接或驗證碼,并且需要發(fā)送到用戶的電子郵件地址。在這種情況下,也需要驗證郵箱格式合法性

public class PasswordServiceImpl implements PasswordService{
    private static final String EMAIL_REGEX =
        "^[A-Za-z0-9+_.-]+@(.+)$";
    public void resetPassword(PasswordInfo passwordInfo) {
        Pattern pattern = Pattern.compile(EMAIL_REGEX);
        Matcher emailMatcher = pattern.matcher(passwordInfo.getEmail());
        if (!emailMatcher.matches()) {
            System.out.println("Invalid email address.");
            return false;
        }
        //發(fā)送通知修改密碼
        sendReSetPasswordNotify();
    }
}

我們可以抽取個校驗郵箱的方法出來,又因為校驗郵箱的功能在不同的類中,因此,我們可以抽個校驗郵箱的工具類

public class EmailValidatorUtil {
    private static final String EMAIL_REGEX =
        "^[A-Za-z0-9+_.-]+@(.+)$";
    private static final Pattern pattern = Pattern.compile(EMAIL_REGEX);
    public static boolean isValid(String email) {
        Matcher matcher = pattern.matcher(email);
        return matcher.matches();
    }
}
//注冊的代碼可以簡化為這樣啦
public class RegisterServiceImpl implements RegisterService{
    public boolean registerUser(UserInfoReq userInfo) {
        if (!EmailValidatorUtil.isValid(userInfo.getEmail())) {
            System.out.println("Invalid email address.");
            return false;
        }
        // 進(jìn)行其他用戶注冊邏輯,比如保存用戶信息到數(shù)據(jù)庫等
        // 返回注冊結(jié)果
        return true;
    }
}

3. 反射

我們?nèi)粘i_發(fā)中,經(jīng)常需要進(jìn)行PO、DTO和VO的轉(zhuǎn)化。所以大家經(jīng)??吹筋愃频拇a:

    //DTO 轉(zhuǎn)VO
    public UserInfoVO convert(UserInfoDTO userInfoDTO) {
        UserInfoVO userInfoVO = new UserInfoVO();
        userInfoVO.setUserName(userInfoDTO.getUserName());
        userInfoVO.setAge(userInfoDTO.getAge());
        return userInfoVO;
    }
      //PO 轉(zhuǎn)DTO
    public UserInfoDTO convert(UserInfoPO userInfoPO) {
        UserInfoDTO userInfoDTO = new UserInfoDTO();
        userInfoDTO.setUserName(userInfoPO.getUserName());
        userInfoDTO.setAge(userInfoPO.getAge());
        return userInfoDTO;
    }

我們可以使用BeanUtils.copyProperties() 去除重復(fù)代碼BeanUtils.copyProperties()底層就是使用了反射

    public UserInfoVO convert(UserInfoDTO userInfoDTO) {
        UserInfoVO userInfoVO = new UserInfoVO();
        BeanUtils.copyProperties(userInfoDTO, userInfoVO);
        return userInfoVO;
    }
    public UserInfoDTO convert(UserInfoPO userInfoPO) {
        UserInfoDTO userInfoDTO = new UserInfoDTO();
        BeanUtils.copyProperties(userInfoPO,userInfoDTO);
        return userInfoDTO;
    }

4.泛型

泛型是如何去除重復(fù)代碼的呢?給大家看個例子,我有個轉(zhuǎn)賬明細(xì)和轉(zhuǎn)賬余額對比的業(yè)務(wù)需求,有兩個類似這樣的方法:

private void getAndUpdateBalanceResultMap(String key, Map<String, List<TransferBalanceDTO>> compareResultListMap,
List<TransferBalanceDTO> balanceDTOs) {
    List<TransferBalanceDTO> tempList = compareResultListMap.getOrDefault(key, new ArrayList<>());
    tempList.addAll(balanceDTOs);
    compareResultListMap.put(key, tempList);
}
private void getAndUpdateDetailResultMap(String key, Map<String, List<TransferDetailDTO>> compareResultListMap,
                                          List<TransferDetailDTO> detailDTOS) {
    List<TransferDetailDTO> tempList = compareResultListMap.getOrDefault(key, new ArrayList<>());
    tempList.addAll(detailDTOS);
    compareResultListMap.put(key, tempList);
}

這兩塊代碼,流程功能看著很像,但是就是不能直接合并抽取一個公用方法,因為類型不一致。單純類型不一樣的話,我們可以結(jié)合泛型處理,因為泛型的本質(zhì)就是參數(shù)化類型.優(yōu)化為這樣:

private <T> void getAndUpdateResultMap(String key, Map<String, List<T>> compareResultListMap, List<T> accountingDTOS) {
List<T> tempList = compareResultListMap.getOrDefault(key, new ArrayList<>());
tempList.addAll(accountingDTOS);
compareResultListMap.put(key, tempList);
}

5. 繼承與多態(tài)

假設(shè)你正在開發(fā)一個電子商務(wù)平臺,需要處理不同類型的訂單,例如普通訂單和折扣訂單。每種訂單都有一些共同的屬性(如訂單號、購買商品列表)和方法(如計算總價、生成訂單報告),但折扣訂單還有特定的屬性和方法。

在沒有使用繼承和多態(tài)的話,會寫出類似這樣的代碼:

//普通訂單
public class Order {
    private String orderNumber;
    private List<Product> products;
    public Order(String orderNumber, List<Product> products) {
        this.orderNumber = orderNumber;
        this.products = products;
    }
    public double calculateTotalPrice() {
        double total = 0;
        for (Product product : products) {
            total += product.getPrice();
        }
        return total;
    }
      public String generateOrderReport() {
        return "Order Report for " + orderNumber + ": Total Price = $" + calculateTotalPrice();
    }
}
//折扣訂單
public class DiscountOrder {
    private String orderNumber;
    private List<Product> products;
    private double discountPercentage;
    public DiscountOrder(String orderNumber, List<Product> products, double discountPercentage) {
        this.orderNumber = orderNumber;
        this.products = products;
        this.discountPercentage = discountPercentage;
    }
    public double calculateTotalPrice() {
        double total = 0;
        for (Product product : products) {
            total += product.getPrice();
        }
        return total - (total * discountPercentage / 100);
    }
      public String generateOrderReport() {
        return "Order Report for " + orderNumber + ": Total Price = $" + calculateTotalPrice();
    }
}

顯然,看到在OrderDiscountOrder類中,generateOrderReport() 方法的代碼是完全相同的。calculateTotalPrice()則是有一點點區(qū)別,但也大相徑庭。

我們可以使用繼承和多態(tài)去除重復(fù)代碼,讓DiscountOrder去繼承Order,代碼如下:

public class Order {
    private String orderNumber;
    private List<Product> products;
    public Order(String orderNumber, List<Product> products) {
        this.orderNumber = orderNumber;
        this.products = products;
    }
    public double calculateTotalPrice() {
        double total = 0;
        for (Product product : products) {
            total += product.getPrice();
        }
        return total;
    }
    public String generateOrderReport() {
        return "Order Report for " + orderNumber + ": Total Price = $" + calculateTotalPrice();
    }
}
public class DiscountOrder extends Order {
    private double discountPercentage;
    public DiscountOrder(String orderNumber, List<Product> products, double discountPercentage) {
        super(orderNumber, products);
        this.discountPercentage = discountPercentage;
    }
    @Override
    public double calculateTotalPrice() {
        double total = super.calculateTotalPrice();
        return total - (total * discountPercentage / 100);
    }
}

6.使用設(shè)計模式

很多設(shè)計模式可以減少重復(fù)代碼、提高代碼的可讀性、可擴(kuò)展性.比如:

  • 工廠模式: 通過工廠模式,你可以將對象的創(chuàng)建和使用分開,從而減少重復(fù)的創(chuàng)建代碼
  • 策略模式: 策略模式定義了一族算法,將它們封裝成獨立的類,并使它們可以互相替換。通過使用策略模式,你可以減少在代碼中重復(fù)使用相同的邏輯。
  • 模板方法模式:模板方法模式定義了一個算法的骨架,將一些步驟延遲到子類中實現(xiàn)。這有助于避免在不同類中重復(fù)編寫相似的代碼。

我給大家舉個例子,模板方法是如何去除重復(fù)代碼的吧,業(yè)務(wù)場景:

假設(shè)你正在開發(fā)一個咖啡和茶的制作流程,制作過程中的熱水和添加物質(zhì)的步驟是相同的,但是具體的飲品制作步驟是不同的

如果沒有使用模板方法模式,實現(xiàn)是醬紫的:

public class Coffee {
    public void prepareCoffee() {
        boilWater();
        brewCoffeeGrinds();
        pourInCup();
        addCondiments();
    }
    private void boilWater() {
        System.out.println("Boiling water");
    }
    private void brewCoffeeGrinds() {
        System.out.println("Brewing coffee grinds");
    }
    private void pourInCup() {
        System.out.println("Pouring into cup");
    }
    private void addCondiments() {
        System.out.println("Adding sugar and milk");
    }
}
public class Tea {
    public void prepareTea() {
        boilWater();
        steepTeaBag();
        pourInCup();
        addLemon();
    }
    private void boilWater() {
        System.out.println("Boiling water");
    }
    private void steepTeaBag() {
        System.out.println("Steeping the tea bag");
    }
    private void pourInCup() {
        System.out.println("Pouring into cup");
    }
    private void addLemon() {
        System.out.println("Adding lemon");
    }
}

這個代碼例子,我們可以發(fā)現(xiàn),燒水和倒入杯子的步驟代碼,在CoffeeTea類中是重復(fù)的。

使用模板方法模式,代碼可以優(yōu)化成這樣:

abstract class Beverage {
    public final void prepareBeverage() {
        boilWater();
        brew();
        pourInCup();
        addCondiments();
    }
    private void boilWater() {
        System.out.println("Boiling water");
    }
    abstract void brew();
    private void pourInCup() {
        System.out.println("Pouring into cup");
    }
    abstract void addCondiments();
}
class Coffee extends Beverage {
    @Override
    void brew() {
        System.out.println("Brewing coffee grinds");
    }
    @Override
    void addCondiments() {
        System.out.println("Adding sugar and milk");
    }
}
class Tea extends Beverage {
    @Override
    void brew() {
        System.out.println("Steeping the tea bag");
    }
    @Override
    void addCondiments() {
        System.out.println("Adding lemon");
    }
}

在這個例子中,我們創(chuàng)建了一個抽象類Beverage,其中定義了制作飲品的模板方法 prepareBeverage()。這個方法包含了燒水、倒入杯子等共同的步驟,而將制作過程中的特定步驟 brew() 和 addCondiments() 延遲到子類中實現(xiàn)。這樣,我們避免了在每個具體的飲品類中重復(fù)編寫相同的燒水和倒入杯子的代碼,提高了代碼的可維護(hù)性和重用性。

7.自定義注解(或者說AOP面向切面)

使用 AOP框架可以在不同地方插入通用的邏輯,從而減少代碼重復(fù)。

業(yè)務(wù)場景:

假設(shè)你正在開發(fā)一個Web應(yīng)用程序,需要對不同的Controller方法進(jìn)行權(quán)限檢查。每個Controller方法都需要進(jìn)行類似的權(quán)限驗證,但是重復(fù)的代碼會導(dǎo)致代碼的冗余和維護(hù)困難。

public class MyController {
    public void viewData() {
        if (!User.hasPermission("read")) {
            throw new SecurityException("Insufficient permission to access this resource.");
        }
        // Method implementation
    }
    public void modifyData() {
        if (!User.hasPermission("write")) {
            throw new SecurityException("Insufficient permission to access this resource.");
        }
        // Method implementation
    }
}

你可以看到在每個需要權(quán)限校驗的方法中都需要重復(fù)編寫相同的權(quán)限校驗邏輯,即出現(xiàn)了重復(fù)代碼.我們使用自定義注解的方式能夠?qū)?quán)限校驗邏輯集中管理,通過切面來處理,消除重復(fù)代碼.如下:

@Aspect
@Component
public class PermissionAspect {
    @Before("@annotation(requiresPermission)")
    public void checkPermission(RequiresPermission requiresPermission) {
        String permission = requiresPermission.value();
        if (!User.hasPermission(permission)) {
            throw new SecurityException("Insufficient permission to access this resource.");
        }
    }
}
public class MyController {
    @RequiresPermission("read")
    public void viewData() {
        // Method implementation
    }
    @RequiresPermission("write")
    public void modifyData() {
        // Method implementation
    }
}

就這樣,不管多少個Controller方法需要進(jìn)行權(quán)限檢查,你只需在方法上添加相應(yīng)的注解即可。權(quán)限檢查的邏輯在切面中集中管理,避免了在每個Controller方法中重復(fù)編寫相同的權(quán)限驗證代碼。這大大提高了代碼的可讀性、可維護(hù)性,并避免了代碼冗余。

8.函數(shù)式接口和Lambda表達(dá)式

業(yè)務(wù)場景:

假設(shè)你正在開發(fā)一個應(yīng)用程序,需要根據(jù)不同的條件來過濾一組數(shù)據(jù)。每次過濾的邏輯都可能會有些微的不同,但基本的流程是相似的。

沒有使用函數(shù)式接口和Lambda表達(dá)式的情況:

public class DataFilter {
    public List<Integer> filterPositiveNumbers(List<Integer> numbers) {
        List<Integer> result = new ArrayList<>();
        for (Integer number : numbers) {
            if (number > 0) {
                result.add(number);
            }
        }
        return result;
    }
    public List<Integer> filterEvenNumbers(List<Integer> numbers) {
        List<Integer> result = new ArrayList<>();
        for (Integer number : numbers) {
            if (number % 2 == 0) {
                result.add(number);
            }
        }
        return result;
    }
}

在這個例子中,我們有兩個不同的方法來過濾一組數(shù)據(jù),但是基本的循環(huán)和條件判斷邏輯是重復(fù)的,我們可以使用使用函數(shù)式接口和Lambda表達(dá)式,去除重復(fù)代碼,如下:

public class DataFilter {
    public List<Integer> filterNumbers(List<Integer> numbers, Predicate<Integer> predicate) {
        List<Integer> result = new ArrayList<>();
        for (Integer number : numbers) {
            if (predicate.test(number)) {
                result.add(number);
            }
        }
        return result;
    }
}

我們將過濾的核心邏輯抽象出來。該方法接受一個 Predicate函數(shù)式接口作為參數(shù),以便根據(jù)不同的條件來過濾數(shù)據(jù)。然后,我們可以使用Lambda表達(dá)式來傳遞具體的條件,這樣最終也達(dá)到去除重復(fù)代碼的效果啦.

以上就是Java優(yōu)化重復(fù)冗余代碼的8種方式總結(jié)的詳細(xì)內(nèi)容,更多關(guān)于Java優(yōu)化代碼的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java多線程、線程安全、線程池創(chuàng)建方式

    Java多線程、線程安全、線程池創(chuàng)建方式

    本文詳細(xì)介紹了多線程的基本概念、創(chuàng)建方式、常用方法、線程安全問題解決以及線程池的使用,通過具體案例和代碼示例,幫助讀者理解多線程在Java中的應(yīng)用和實現(xiàn),感興趣的朋友跟隨小編一起看看吧
    2026-03-03
  • Spring Boot 2.x中Actuator的一些知識點

    Spring Boot 2.x中Actuator的一些知識點

    這篇文章主要給大家介紹了關(guān)于Spring Boot 2.x中Actuator的一些知識點,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Spring Boot 2.x具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • SpringBoot使用AES對JSON數(shù)據(jù)加密和解密的實現(xiàn)方法

    SpringBoot使用AES對JSON數(shù)據(jù)加密和解密的實現(xiàn)方法

    這篇文章主要介紹了SpringBoot使用AES對JSON數(shù)據(jù)加密和解密的實現(xiàn)方法,文章通過代碼示例介紹的非常詳細(xì),對我們的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2023-08-08
  • 基于JAVA每月運勢api調(diào)用代碼實例

    基于JAVA每月運勢api調(diào)用代碼實例

    這篇文章主要為大家詳細(xì)介紹了JAVA每月運勢api調(diào)用代碼實例,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • Spring事務(wù)失效場景原理及解決方案

    Spring事務(wù)失效場景原理及解決方案

    這篇文章主要介紹了Spring事務(wù)失效場景原理及解決方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-09-09
  • Servlet第一個項目的發(fā)布(入門)

    Servlet第一個項目的發(fā)布(入門)

    這篇文章主要介紹了Servlet第一個項目的發(fā)布,下面是用servlet實現(xiàn)的一個簡單的web項目,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2021-04-04
  • Struts2實現(xiàn)文件下載功能代碼分享(文件名中文轉(zhuǎn)碼)

    Struts2實現(xiàn)文件下載功能代碼分享(文件名中文轉(zhuǎn)碼)

    這篇文章主要介紹了Struts2實現(xiàn)文件下載功能代碼分享(文件名中文轉(zhuǎn)碼)的相關(guān)資料,需要的朋友可以參考下
    2016-06-06
  • Java各種比較對象的方式的對比總結(jié)

    Java各種比較對象的方式的對比總結(jié)

    比較對象是面向?qū)ο缶幊陶Z言的一個基本特征.在本教程中,我們將介紹Java語言的一些特性,這些特性允許我們比較對象.此外,我們還將研究外部庫中的這些特性,需要的朋友可以參考下
    2021-06-06
  • java加密枝術(shù)深入理解

    java加密枝術(shù)深入理解

    java.security包中的MessageDigest類提供了計算消息摘要的方法,本文將詳細(xì)介紹,需要了解的朋友可以參考下
    2012-11-11
  • SpringBoot實現(xiàn)過濾器攔截器的耗時對比

    SpringBoot實現(xiàn)過濾器攔截器的耗時對比

    這篇文章主要為大家詳細(xì)介紹了SpringBoot實現(xiàn)過濾器攔截器的輸出接口耗時對比,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2022-06-06

最新評論

巴塘县| 阿勒泰市| 开化县| 新密市| 定陶县| 屏东县| 河北区| 南靖县| 汉川市| 扬州市| 阿荣旗| 石台县| 东阳市| 定边县| 滨州市| 陵水| 江门市| 桐庐县| 镇宁| 东山县| 广宁县| 兴安盟| 苍溪县| 长垣县| 中方县| 潼南县| 册亨县| 峨山| 友谊县| 吉水县| 环江| 安西县| 长垣县| 兴化市| 庆云县| 龙山县| 大埔县| 广昌县| 福鼎市| 黎城县| 泾川县|