精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

代碼重構的15個小技巧

開發 前端
在這篇文章中,我們探討了15個代碼重構的小技巧,從簡單的提取方法到高級的設計模式應用。這些技巧可以幫助我們寫出更加簡潔、可讀、可維護的代碼。代碼重構是一個持續的過程,我們應該在日常開發中不斷地應用這些技巧,逐步改進我們的代碼質量。

前言

相信很多小伙伴在日常工作中都會遇到這樣的情況:接手了一個歷史項目,代碼像一團亂麻。

或者自己寫的代碼隨著業務的不斷迭代,變得越來越臃腫難以維護。

這時候,代碼重構就顯得尤為重要了。

那么,如何進行高效的代碼重構呢?

這篇文章我跟大家大家一起聊聊15個實用的代碼重構技巧,希望對你會有所幫助。

1. 提取方法

有些小伙伴在工作中可能會寫出這樣的代碼:一個方法幾百行,里面包含了各種業務邏輯。

這樣的代碼不僅難以閱讀,也難以維護和測試。

重構前:

public void processOrder(Order order) {
    // 驗證訂單
    if (order == null) {
        throw new IllegalArgumentException("訂單不能為空");
    }
    if (order.getItems() == null || order.getItems().isEmpty()) {
        throw new IllegalArgumentException("訂單項不能為空");
    }
    if (order.getCustomer() == null) {
        throw new IllegalArgumentException("客戶信息不能為空");
    }
    
    // 計算訂單總價
    double total = 0;
    for (OrderItem item : order.getItems()) {
        double price = item.getPrice();
        int quantity = item.getQuantity();
        total += price * quantity;
    }
    
    // 應用折扣
    if (order.getCustomer().isVip()) {
        total = total * 0.9;
    }
    
    // 保存訂單
    order.setTotal(total);
    orderRepository.save(order);
    
    // 發送通知
    String message = "訂單" + order.getId() + "已處理,總價:" + 
    total;
    emailService.sendEmail(order.getCustomer().getEmail(), "訂單處理
    通知", message);
    smsService.sendSms(order.getCustomer().getPhone(), message);
}

重構后:

public void processOrder(Order order) {
    validateOrder(order);
    double total = calculateOrderTotal(order);
    total = applyDiscount(order, total);
    saveOrder(order, total);
    sendNotifications(order, total);
}

private void validateOrder(Order order) {
    if (order == null) {
        thrownew IllegalArgumentException("訂單不能為空");
    }
    if (order.getItems() == null || order.getItems().isEmpty()) {
        thrownew IllegalArgumentException("訂單項不能為空");
    }
    if (order.getCustomer() == null) {
        thrownew IllegalArgumentException("客戶信息不能為空");
    }
}

private double calculateOrderTotal(Order order) {
    double total = 0;
    for (OrderItem item : order.getItems()) {
        double price = item.getPrice();
        int quantity = item.getQuantity();
        total += price * quantity;
    }
    return total;
}

private double applyDiscount(Order order, double total) {
    if (order.getCustomer().isVip()) {
        return total * 0.9;
    }
    return total;
}

private void saveOrder(Order order, double total) {
    order.setTotal(total);
    orderRepository.save(order);
}

private void sendNotifications(Order order, double total) {
    String message = "訂單" + order.getId() + "已處理,總價:" + 
    total;
    emailService.sendEmail(order.getCustomer().getEmail(), "訂單處理
    通知", message);
    smsService.sendSms(order.getCustomer().getPhone(), message);
}

通過提取方法,我們將一個大方法拆分成了多個小方法,每個方法只負責一個功能。

這樣不僅提高了代碼的可讀性,也使得每個方法更容易測試和維護。

2. 引入解釋性變量

有時候,一個復雜的表達式可能難以理解。

這時,我們可以引入一個解釋性變量來提高代碼的可讀性。

重構前:

public boolean isEligibleForDiscount(Customer customer, Order 
order) {
    return (customer.getAge() >= 60 || (customer.getMembershipYears
    () > 5 && order.getTotal() > 1000)) && !customer.
    hasOutstandingPayments();
}

重構后:

public boolean isEligibleForDiscount(Customer customer, Order 
order) {
    boolean isSenior = customer.getAge() >= 60;
    boolean isLoyalCustomerWithLargeOrder = customer.
    getMembershipYears() > 5 && order.getTotal() > 1000;
    boolean hasNoOutstandingPayments = !customer.
    hasOutstandingPayments();
    
    return (isSenior || isLoyalCustomerWithLargeOrder) && 
    hasNoOutstandingPayments;
}

通過引入解釋性變量,我們使得復雜的條件表達式更加清晰易懂。每個變量都有一個描述性的名稱,使得代碼的意圖更加明確。

3. 替換條件表達式

有些小伙伴在處理不同類型的對象時,可能會使用大量的條件語句(if-else或switch)。

這樣的代碼不僅冗長,而且每次添加新類型都需要修改這些條件語句,違反了開閉原則。

重構前:

public class PaymentProcessor {
    public void processPayment(Payment payment) {
        if (payment.getType().equals("CREDIT_CARD")) {
            // 處理信用卡支付
            validateCreditCard(payment);
            chargeCreditCard(payment);
        } else if (payment.getType().equals("PAYPAL")) {
            // 處理PayPal支付
            validatePayPalAccount(payment);
            chargePayPalAccount(payment);
        } else if (payment.getType().equals("BANK_TRANSFER")) {
            // 處理銀行轉賬
            validateBankAccount(payment);
            initiateTransfer(payment);
        } else {
            throw new IllegalArgumentException("不支持的支付類型:" + 
            payment.getType());
        }
    }
    
    // 其他方法...
}

重構后:

public interface PaymentProcessor {
    void processPayment(Payment payment);
}

public class CreditCardProcessor implements PaymentProcessor {
    @Override
    public void processPayment(Payment payment) {
        validateCreditCard(payment);
        chargeCreditCard(payment);
    }
    
    // 其他方法...
}

public class PayPalProcessor implements PaymentProcessor {
    @Override
    public void processPayment(Payment payment) {
        validatePayPalAccount(payment);
        chargePayPalAccount(payment);
    }
    
    // 其他方法...
}

public class BankTransferProcessor implements PaymentProcessor {
    @Override
    public void processPayment(Payment payment) {
        validateBankAccount(payment);
        initiateTransfer(payment);
    }
    
    // 其他方法...
}

public class PaymentFactory {
    public static PaymentProcessor getProcessor(String paymentType) 
    {
        if (paymentType.equals("CREDIT_CARD")) {
            return new CreditCardProcessor();
        } elseif (paymentType.equals("PAYPAL")) {
            return new PayPalProcessor();
        } elseif (paymentType.equals("BANK_TRANSFER")) {
            return new BankTransferProcessor();
        } else {
            throw new IllegalArgumentException("不支持的支付類型:" + 
            paymentType);
        }
    }
}

// 使用
PaymentProcessor processor = PaymentFactory.getProcessor(payment.
getType());
processor.processPayment(payment);

通過使用多態,我們將不同類型的支付處理邏輯分散到各自的類中,使得代碼更加模塊化,也更容易擴展。

當需要添加新的支付類型時,只需創建一個新的處理器類,而不需要修改現有的代碼。

4. 移除重復代碼

代碼重復是軟件開發中的一大問題。

重復的代碼不僅增加了代碼量,也增加了維護的難度。當需要修改一個功能時,可能需要在多個地方進行相同的修改,這增加了出錯的可能性。

重構前:

public class UserService {
    public User findUserById(Long id) {
        // 記錄日志
        Logger logger = LoggerFactory.getLogger(UserService.class);
        logger.info("查詢用戶,ID:" + id);
        
        // 查詢用戶
        User user = userRepository.findById(id);
        if (user == null) {
            logger.error("用戶不存在,ID:" + id);
            thrownew UserNotFoundException("用戶不存在,ID:" + id);
        }
        
        return user;
    }
    
    public User findUserByEmail(String email) {
        // 記錄日志
        Logger logger = LoggerFactory.getLogger(UserService.class);
        logger.info("查詢用戶,Email:" + email);
        
        // 查詢用戶
        User user = userRepository.findByEmail(email);
        if (user == null) {
            logger.error("用戶不存在,Email:" + email);
            thrownew UserNotFoundException("用戶不存在,Email:" + 
            email);
        }
        
        return user;
    }
}

重構后:

public class UserService {
    private static final Logger logger = LoggerFactory.getLogger
    (UserService.class);
    
    public User findUserById(Long id) {
        logger.info("查詢用戶,ID:" + id);
        return findUserOrThrow(() -> userRepository.findById(id), "
        用戶不存在,ID:" + id);
    }
    
    public User findUserByEmail(String email) {
        logger.info("查詢用戶,Email:" + email);
        return findUserOrThrow(() -> userRepository.findByEmail
        (email), "用戶不存在,Email:" + email);
    }
    
    private User findUserOrThrow(Supplier<User> finder, String 
    errorMessage) {
        User user = finder.get();
        if (user == null) {
            logger.error(errorMessage);
            throw new UserNotFoundException(errorMessage);
        }
        return user;
    }
}

通過提取公共方法,我們消除了重復代碼,使得代碼更加簡潔。

當需要修改查詢用戶的邏輯時,只需要修改一個地方,而不是多個地方。

5. 引入參數對象

當一個方法有多個參數時,特別是當這些參數經常一起出現時,可以考慮將它們封裝成一個對象。

重構前:

public class ReportGenerator {
    public Report generateReport(String startDate, String endDate, 
    String department, String format, boolean includeCharts) {
        // 生成報告的邏輯
        // ...
    }
    
    public void emailReport(String startDate, String endDate, 
    String department, String format, boolean includeCharts, String 
    email) {
        Report report = generateReport(startDate, endDate, 
        department, format, includeCharts);
        // 發送報告的邏輯
        // ...
    }
    
    public void saveReport(String startDate, String endDate, String 
    department, String format, boolean includeCharts, String 
    filePath) {
        Report report = generateReport(startDate, endDate, 
        department, format, includeCharts);
        // 保存報告的邏輯
        // ...
    }
}

重構后:

public class ReportCriteria {
    private String startDate;
    private String endDate;
    private String department;
    private String format;
    private boolean includeCharts;
    
    // 構造函數、getter和setter
    // ...
}

public class ReportGenerator {
    public Report generateReport(ReportCriteria criteria) {
        // 生成報告的邏輯
        // ...
    }
    
    public void emailReport(ReportCriteria criteria, String email) {
        Report report = generateReport(criteria);
        // 發送報告的邏輯
        // ...
    }
    
    public void saveReport(ReportCriteria criteria, String 
    filePath) {
        Report report = generateReport(criteria);
        // 保存報告的邏輯
        // ...
    }
}

通過引入參數對象,我們減少了方法的參數數量,使得方法調用更加簡潔。同時,參數對象也可以包含與這些參數相關的行為,進一步提高代碼的內聚性。

6. 使用策略模式

有些小伙伴在處理不同的算法或策略時,可能會使用大量的條件語句。

這樣的代碼不僅難以維護,也難以擴展。

重構前:

public class ShippingCalculator {
    public double calculateShippingCost(Order order, String 
    shippingMethod) {
        if (shippingMethod.equals("STANDARD")) {
            // 標準運費計算邏輯
            return order.getWeight() * 0.5;
        } else if (shippingMethod.equals("EXPRESS")) {
            // 快遞運費計算邏輯
            return order.getWeight() * 1.0 + 10;
        } else if (shippingMethod.equals("OVERNIGHT")) {
            // 隔夜運費計算邏輯
            return order.getWeight() * 1.5 + 20;
        } else {
            throw new IllegalArgumentException("不支持的運輸方式:" + 
            shippingMethod);
        }
    }
}

重構后:

public interface ShippingStrategy {
    double calculateShippingCost(Order order);
}

public class StandardShipping implements ShippingStrategy {
    @Override
    public double calculateShippingCost(Order order) {
        return order.getWeight() * 0.5;
    }
}

public class ExpressShipping implements ShippingStrategy {
    @Override
    public double calculateShippingCost(Order order) {
        return order.getWeight() * 1.0 + 10;
    }
}

public class OvernightShipping implements ShippingStrategy {
    @Override
    public double calculateShippingCost(Order order) {
        return order.getWeight() * 1.5 + 20;
    }
}

public class ShippingCalculator {
    private Map<String, ShippingStrategy> strategies = new HashMap<>
    ();
    
    public ShippingCalculator() {
        strategies.put("STANDARD", new StandardShipping());
        strategies.put("EXPRESS", new ExpressShipping());
        strategies.put("OVERNIGHT", new OvernightShipping());
    }
    
    public double calculateShippingCost(Order order, String 
    shippingMethod) {
        ShippingStrategy strategy = strategies.get(shippingMethod);
        if (strategy == null) {
            thrownew IllegalArgumentException("不支持的運輸方式:" + 
            shippingMethod);
        }
        return strategy.calculateShippingCost(order);
    }
}

通過使用策略模式,我們將不同的運費計算邏輯分散到各自的類中,使得代碼更加模塊化,也更容易擴展。

當需要添加新的運輸方式時,只需創建一個新的策略類,并將其添加到策略映射中,而不需要修改現有的代碼。

7. 使用構建者模式

當一個類有多個構造參數時,特別是當有些參數是可選的時,可以考慮使用構建者模式。

重構前:

public class User {
    private String username;
    private String email;
    private String firstName;
    private String lastName;
    private String phone;
    private String address;
    private String city;
    private String country;
    private String postalCode;
    
    // 構造函數
    public User(String username, String email) {
        this.username = username;
        this.email = email;
    }
    
    public User(String username, String email, String firstName, 
    String lastName) {
        this.username = username;
        this.email = email;
        this.firstName = firstName;
        this.lastName = lastName;
    }
    
    public User(String username, String email, String firstName, 
    String lastName, String phone) {
        this.username = username;
        this.email = email;
        this.firstName = firstName;
        this.lastName = lastName;
        this.phone = phone;
    }
    
    // 更多構造函數...
    
    // getter和setter
    // ...
}

重構后:

public class User {
    private String username;
    private String email;
    private String firstName;
    private String lastName;
    private String phone;
    private String address;
    private String city;
    private String country;
    private String postalCode;
    
    private User(Builder builder) {
        this.username = builder.username;
        this.email = builder.email;
        this.firstName = builder.firstName;
        this.lastName = builder.lastName;
        this.phone = builder.phone;
        this.address = builder.address;
        this.city = builder.city;
        this.country = builder.country;
        this.postalCode = builder.postalCode;
    }
    
    // getter(沒有setter,使對象不可變)
    // ...
    
    public static class Builder {
        // 必需參數
        private final String username;
        private final String email;
        
        // 可選參數
        private String firstName;
        private String lastName;
        private String phone;
        private String address;
        private String city;
        private String country;
        private String postalCode;
        
        public Builder(String username, String email) {
            this.username = username;
            this.email = email;
        }
        
        public Builder firstName(String firstName) {
            this.firstName = firstName;
            return this;
        } 
        
        public Builder lastName(String lastName) {
            this.lastName = lastName;
            return this;
        }
         
        public Builder phone(String phone) {
            this.phone = phone;
            return this;
        }
        
        public Builder address(String address) {
            this.address = address;
            return this;
        }
        
        public Builder city(String city) {
            this.city = city;
            returnthis;
        }
        
        public Builder country(String country) {
            this.c ountry = country;
            return this;
        }
        
        public Builder postalCode(String postalCode) {
            this.postalCode = postalCode;
            return this;
        }
        
        public User build() {
            return new User(this);
        }
    }
}

// 使用
User user = new User.Builder("johndoe", "john.doe@example.com")
    .firstName("John")
    .lastName("Doe")
    .phone("1234567890")
    .build();

通過使用構建者模式,我們解決了構造函數參數過多的問題,使得對象創建更加靈活和可讀。

同時,構建者模式也可以確保對象在創建后是不可變的,提高了代碼的安全性。

8. 使用工廠方法

當對象的創建邏輯比較復雜時,可以考慮使用工廠方法。

重構前:

public class ProductService {
    public Product createProduct(String type, String name, double 
    price) {
        Product product;
        if (type.equals("PHYSICAL")) {
            product = new PhysicalProduct(name, price);
            // 設置物理產品的屬性
            // ...
        } else if (type.equals("DIGITAL")) {
            product = new DigitalProduct(name, price);
            // 設置數字產品的屬性
            // ...
        } else if (type.equals("SUBSCRIPTION")) {
            product = new SubscriptionProduct(name, price);
            // 設置訂閱產品的屬性
            // ...
        } else {
            throw new IllegalArgumentException("不支持的產品類型:" + 
            type);
        }
        return product;
    }
}

重構后:

public abstract class ProductFactory {
    public static Product createProduct(String type, String name, 
    double price) {
        if (type.equals("PHYSICAL")) {
            return createPhysicalProduct(name, price);
        } else if (type.equals("DIGITAL")) {
            return createDigitalProduct(name, price);
        } else if (type.equals("SUBSCRIPTION")) {
            return createSubscriptionProduct(name, price);
        } else {
            thrownew IllegalArgumentException("不支持的產品類型:" + 
            type);
        }
    }
    
    private static Product createPhysicalProduct(String name, 
    double price) {
        PhysicalProduct product = new PhysicalProduct(name, price);
        // 設置物理產品的屬性
        // ...
        return product;
    }
    
    private static Product createDigitalProduct(String name, double 
    price) {
        DigitalProduct product = new DigitalProduct(name, price);
        // 設置數字產品的屬性
        // ...
        return product;
    }
    
    private static Product createSubscriptionProduct(String name, 
    double price) {
        SubscriptionProduct product = new SubscriptionProduct(name, 
        price);
        // 設置訂閱產品的屬性
        // ...
        return product;
    }
}

// 使用
Product product = ProductFactory.createProduct("PHYSICAL", "書籍", 
29.99);

通過使用工廠方法,我們將對象的創建邏輯從客戶端代碼中分離出來,使得代碼更加模塊化,也更容易維護。

當需要添加新的產品類型時,只需在工廠類中添加相應的創建方法,而不需要修改客戶端代碼。

9. 使用Optional避免空指針異常

空指針異常(NullPointerException)是Java中最常見的異常之一。

為了避免這種異常,我們可以使用Java 8引入的Optional類。

重構前:

public class UserService {
    public User findUserById(Long id) {
        // 查詢用戶
        return userRepository.findById(id);
    }
    
    public String getUserEmail(Long id) {
        User user = findUserById(id);
        if (user != null) {
            String email = user.getEmail();
            if (email != null) {
                return email;
            }
        }
        return"未知";
    }
}

重構后:

public class UserService {
    public Optional<User> findUserById(Long id) {
        // 查詢用戶
        User user = userRepository.findById(id);
        return Optional.ofNullable(user);
    }
    
    public String getUserEmail(Long id) {
        return findUserById(id)
            .map(User::getEmail)
            .orElse("未知");
    }
}

通過使用Optional,我們明確表示方法可能返回空值,使得代碼更加清晰。

同時,Optional提供了豐富的API,如map、filter、orElse等,使得處理可能為空的值更加方便。

10. 使用Stream API簡化集合操作

Java 8引入的Stream API提供了一種函數式編程的方式來處理集合,使得代碼更加簡潔和可讀。

重構前:

public class OrderService {
    public List<Order> findLargeOrders(List<Order> orders) {
        List<Order> largeOrders = new ArrayList<>();
        for (Order order : orders) {
            if (order.getTotal() > 1000) {
                largeOrders.add(order);
            }
        }
        return largeOrders;
    }
    
    public double calculateTotalRevenue(List<Order> orders) {
        double total = 0;
        for (Order order : orders) {
            total += order.getTotal();
        }
        return total;
    }
    
    public List<String> getCustomerNames(List<Order> orders) {
        List<String> names = new ArrayList<>();
        for (Order order : orders) {
            String name = order.getCustomer().getName();
            if (!names.contains(name)) {
                names.add(name);
            }
        }
        return names;
    }
}

重構后:

public class OrderService {
    public List<Order> findLargeOrders(List<Order> orders) {
        return orders.stream()
            .filter(order -> order.getTotal() > 1000)
            .collect(Collectors.toList());
    }
    
    public double calculateTotalRevenue(List<Order> orders) {
        return orders.stream()
            .mapToDouble(Order::getTotal)
            .sum();
    }
    
    public List<String> getCustomerNames(List<Order> orders) {
        return orders.stream()
            .map(order -> order.getCustomer().getName())
            .distinct()
            .collect(Collectors.toList());
    }
}

通過使用Stream API,我們將命令式的代碼轉換為聲明式的代碼,使得代碼更加簡潔和可讀。

Stream API提供了豐富的操作,如filter、map、reduce等,使得處理集合更加方便。

11. 使用Lambda表達式簡化匿名內部類

Java 8引入的Lambda表達式提供了一種更簡潔的方式來創建匿名函數,特別適合用于替代匿名內部類。

重構前:

public class ButtonHandler {
    public void setupButton(Button button) {
        button.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                // 處理點擊事件
                System.out.println("按鈕被點擊");
            }
        });
    }
    
    public void sortUsers(List<User> users) {
        Collections.sort(users, new Comparator<User>() {
            @Override
            public int compare(User u1, User u2) {
                return u1.getName().compareTo(u2.getName());
            }
        });
    }
}

重構后:

public class ButtonHandler {
    public void setupButton(Button button) {
        button.setOnClickListener(view -> {
            // 處理點擊事件
            System.out.println("按鈕被點擊");
        });
    }
    
    public void sortUsers(List<User> users) {
        Collections.sort(users, (u1, u2) -> u1.getName().compareTo
        (u2.getName()));
        // 或者更簡潔地
        users.sort(Comparator.comparing(User::getName));
    }
}

通過使用Lambda表達式,我們將冗長的匿名內部類替換為簡潔的函數式表達式,使得代碼更加簡潔和可讀。

12. 使用方法引用簡化Lambda表達式

Java 8引入的方法引用提供了一種更簡潔的方式來引用已有的方法,特別適合用于替代簡單的Lambda表達式。

重構前:

public class UserProcessor {
    public List<String> getUserNames(List<User> users) {
        return users.stream()
            .map(user -> user.getName())
            .collect(Collectors.toList());
    }
    
    public void printUsers(List<User> users) {
        users.forEach(user -> System.out.println(user));
    }
    
    public List<User> createUsers(List<String> names) {
        return names.stream()
            .map(name -> new User(name))
            .collect(Collectors.toList());
    }
}

重構后:

public class UserProcessor {
    public List<String> getUserNames(List<User> users) {
        return users.stream()
            .map(User::getName)
            .collect(Collectors.toList());
    }
    
    public void printUsers(List<User> users) {
        users.forEach(System.out::println);
    }
    
    public List<User> createUsers(List<String> names) {
        return names.stream()
            .map(User::new)
            .collect(Collectors.toList());
    }
}

通過使用方法引用,我們將簡單的Lambda表達式替換為更簡潔的方法引用,使得代碼更加簡潔和可讀。

13. 使用CompletableFuture簡化異步編程

Java 8引入的CompletableFuture提供了一種更簡潔的方式來處理異步操作,特別適合用于替代傳統的回調方式。

重構前:

public class UserService {
    public void processUser(Long userId, Callback<User> callback) {
        // 異步查詢用戶
        userRepository.findByIdAsync(userId, new Callback<User>() {
            @Override
            public void onSuccess(User user) {
                // 異步查詢用戶的訂單
                orderRepository.findByUserIdAsync(userId, new
                Callback<List<Order>>() {
                    @Override
                    public void onSuccess(List<Order> orders) {
                        // 處理用戶和訂單
                        user.setOrders(orders);
                        callback.onSuccess(user);
                    }
                    
                    @Override
                    public void onError(Exception e) {
                        callback.onError(e);
                    }
                });
            }
            
            @Override
            public void onError(Exception e) {
                callback.onError(e);
            }
        });
    }
}

重構后:

public class UserService {
    public CompletableFuture<User> processUser(Long userId) {
        return userRepository.findByIdAsync(userId)
            .thenCompose(user -> orderRepository.findByUserIdAsync
            (userId)
                .thenApply(orders -> {
                    user.setOrders(orders);
                    return user;
                }));
    }
}

// 使用
userService.processUser(123L)
    .thenAccept(user -> {
        // 處理用戶
        System.out.println("用戶:" + user.getName());
        System.out.println("訂單數:" + user.getOrders().size());
    })
    .exceptionally(e -> {
        // 處理異常
        System.err.println("處理用戶時出錯:" + e.getMessage());
        returnnull;
    });

通過使用CompletableFuture,我們將嵌套的回調轉換為鏈式的調用,使得代碼更加簡潔和可讀。

CompletableFuture提供了豐富的API,如thenApply、thenCompose、thenAccept等,使得處理異步操作更加方便。

14. 使用接口默認方法簡化接口實現

Java 8引入的接口默認方法允許在接口中提供方法的默認實現,使得接口的演化更加靈活。

重構前:

public interface PaymentProcessor {
    void processPayment(Payment payment);
    void refundPayment(Payment payment);
    void cancelPayment(Payment payment);
}

public class CreditCardProcessor implements PaymentProcessor {
    @Override
    public void processPayment(Payment payment) {
        // 處理信用卡支付
    }
    
    @Override
    public void refundPayment(Payment payment) {
        // 處理信用卡退款
    }
    
    @Override
    public void cancelPayment(Payment payment) {
        // 取消支付并退款
        refundPayment(payment);
    }
}

public class PayPalProcessor implements PaymentProcessor {
    @Override
    public void processPayment(Payment payment) {
        // 處理PayPal支付
    }
    
    @Override
    public void refundPayment(Payment payment) {
        // 處理PayPal退款
    }
    
    @Override
    public void cancelPayment(Payment payment) {
        // 取消支付并退款
        refundPayment(payment);
    }
}

重構后:

public interface PaymentProcessor {
    void processPayment(Payment payment);
    void refundPayment(Payment payment);
    
    default void cancelPayment(Payment payment) {
        // 默認實現:取消支付并退款
        refundPayment(payment);
    }
}

public class CreditCardProcessor implements PaymentProcessor {
    @Override
    public void processPayment(Payment payment) {
        // 處理信用卡支付
    }
    
    @Override
    public void refundPayment(Payment payment) {
        // 處理信用卡退款
    }
}

public class PayPalProcessor implements PaymentProcessor {
    @Override
    public void processPayment(Payment payment) {
        // 處理PayPal支付
    }
    
    @Override
    public void refundPayment(Payment payment) {
        // 處理PayPal退款
    }
}

通過使用接口默認方法,我們將公共的實現從具體的類中提取到接口中,減少了重復代碼。

當需要修改公共實現時,只需修改接口中的默認方法,而不需要修改所有實現類。

15. 使用枚舉替代常量

使用枚舉可以提供類型安全的常量,避免使用魔法數字或字符串常量。

重構前:

public class OrderStatus {
    public static final String PENDING = "PENDING";
    public static final String PROCESSING = "PROCESSING";
    public static final String SHIPPED = "SHIPPED";
    public static final String DELIVERED = "DELIVERED";
    public static final String CANCELLED = "CANCELLED";
}

public class Order {
    private String status;
    
    public void setStatus(String status) {
        this.status = status;
    }
    
    public String getStatus() {
        return status;
    }
    
    public boolean isCancellable() {
        return status.equals(OrderStatus.PENDING) || status.equals
        (OrderStatus.PROCESSING);
    }
}

// 使用
Order order = new Order();
order.setStatus(OrderStatus.PENDING);
// 可能的錯誤:使用了未定義的常量
order.setStatus("REFUNDED");

重構后:

public enum OrderStatus {
    PENDING,
    PROCESSING,
    SHIPPED,
    DELIVERED,
    CANCELLED;
    
    public boolean isCancellable() {
        return this == PENDING || this == PROCESSING;
    }
}

public class Order {
    private OrderStatus status;
    
    public void setStatus(OrderStatus status) {
        this.status = status;
    }
    
    public OrderStatus getStatus() {
        return status;
    }
    
    public boolean isCancellable() {
        return status.isCancellable();
    }
}

// 使用
Order order = new Order();
order.setStatus(OrderStatus.PENDING);
// 編譯錯誤:無法使用未定義的枚舉常量
// order.setStatus("REFUNDED");

通過使用枚舉,我們提供了類型安全的常量,避免了使用魔法數字或字符串常量可能導致的錯誤。

同時,枚舉也可以包含方法,使得與常量相關的行為更加內聚。

總結

在這篇文章中,我們探討了15個代碼重構的小技巧,從簡單的提取方法到高級的設計模式應用。

這些技巧可以幫助我們寫出更加簡潔、可讀、可維護的代碼。

代碼重構是一個持續的過程,我們應該在日常開發中不斷地應用這些技巧,逐步改進我們的代碼質量。

記住,好的代碼不僅僅是能夠正確運行,還應該易于理解、易于修改和易于擴展。

希望這些技巧對你有所幫助,讓我們一起寫出更好的代碼!

責任編輯:武曉燕 來源: 蘇三說技術
相關推薦

2021-11-10 18:52:42

SQL技巧優化

2022-04-02 09:56:44

pipPython

2020-11-11 08:22:40

前端開發JavaScript

2024-08-06 12:35:42

C#代碼重構

2023-07-19 15:16:33

遠程辦公技巧

2022-03-10 08:01:06

CSS技巧選擇器

2020-09-26 21:50:26

JavaScript代碼開發

2022-11-24 10:34:05

CSS前端

2023-10-09 18:13:14

MySQL數據庫查詢

2022-08-26 17:48:34

數據庫建表數據庫

2023-11-26 17:54:07

JavaScript開發

2019-11-05 08:34:33

代碼switch開發

2023-02-06 12:00:00

重構PythonPythonic

2024-12-31 00:00:30

CursorAI編程

2023-09-26 12:04:15

重構技巧Pythonic

2023-01-11 11:35:40

重構PythonPythonic

2022-12-25 16:03:31

JavaScript技巧

2022-12-22 14:44:06

JavaScript技巧

2015-11-19 09:36:13

前端程序員jQuery

2025-04-28 04:22:00

點贊
收藏

51CTO技術棧公眾號

国产a级毛片一区| 欧美日韩中字| 欧美日韩亚洲一区二| 免费av在线一区二区| 中文在线字幕免费观| 女同性一区二区三区人了人一 | 人体内射精一区二区三区| 亚欧洲精品视频| 九色综合狠狠综合久久| 久久久久国产一区二区三区| 成人免费av片| 成人51免费| 福利视频第一区| 99精品视频网站| 亚洲欧洲综合在线| 国产精品一区二区无线| 日韩免费精品视频| 久久香蕉精品视频| sdde在线播放一区二区| 亚洲国产日韩一区| 国内av一区二区| 中文字幕在线高清| 有坂深雪av一区二区精品| 日本精品一区| 日韩在线视频免费| 国产一区不卡精品| 国产精品久久久久久网站| 国产乡下妇女做爰| 亚洲国产老妈| 在线成人激情视频| 网站免费在线观看| 97久久综合精品久久久综合| 91精品国产aⅴ一区二区| 成人一级片网站| 国内老司机av在线| 欧美国产激情一区二区三区蜜月| 精品国产一区二区三区日日嗨| 国产内射老熟女aaaa∵| 日韩成人一级片| 97视频在线观看免费| 免费看一级一片| 郴州新闻综合频道在线直播| 亚洲欧美日韩精品久久奇米色影视| 国产黑丝在线视频| 色成人综合网| 欧美色网一区二区| 男人搞女人网站| 国产精品亚洲一区二区三区在线观看 | 午夜在线视频一区二区区别| 久久免费精品视频| 久久久久成人片免费观看蜜芽 | 免费在线观看视频a| √天堂8在线网| 亚洲私人黄色宅男| 一本二本三本亚洲码| 欧美69xxx| 中文字幕在线不卡视频| 亚洲巨乳在线观看| 一级毛片视频在线| 国产精品对白交换视频| 亚洲欧美日韩另类精品一区二区三区| 国产youjizz在线| 亚洲国产精品99久久久久久久久| 神马影院我不卡| 生活片a∨在线观看| 国产精品激情偷乱一区二区∴| 亚洲欧美久久234| 国产视频在线播放| 亚洲综合久久久| 日韩精品一区在线视频| 国产在线天堂www网在线观看| 欧美日韩色婷婷| 红桃av在线播放| 日本一区二区三区视频在线| 欧美日韩高清一区二区三区| 欧美视频亚洲图片| 亚洲一区二区三区日本久久九| 日韩欧美一卡二卡| 午夜视频在线观看国产| 亚洲欧美日本伦理| 爽爽爽爽爽爽爽成人免费观看| 五月天免费网站| 欧美99久久| 91av在线影院| 中文字幕永久免费视频| 国产精品88888| 久久99精品久久久久久青青日本 | 久久综合九色九九| 免费视频一二三区| 蜜桃伊人久久| 97久久天天综合色天天综合色hd| 色哟哟国产精品色哟哟| 国产精品人成在线观看免费| 成人午夜免费在线视频| 92久久精品| 欧美在线|欧美| 亚洲精品成人无码毛片| 欧美军人男男激情gay| 欧美伦理91i| 亚洲另类在线观看| 国产乱码精品一区二区三区五月婷| 精品欧美一区二区三区久久久 | 日本三级久久| 日韩视频―中文字幕| 国产无遮挡免费视频| 美女视频黄频大全不卡视频在线播放| 国产精品区二区三区日本| 国产福利片在线| 亚洲国产精品久久久久婷婷884| 免费激情视频在线观看| 亚洲综合网站| 视频在线观看一区二区| 日韩欧美一级视频| 国产中文字幕精品| 欧美三级网色| 美女高潮视频在线看| 制服丝袜av成人在线看| 丰满圆润老女人hd| 亚洲五月婷婷| 91热福利电影| av小片在线| 精品久久久香蕉免费精品视频| 91精产国品一二三产区别沈先生| 亚洲精华一区二区三区| 欧美黄色三级网站| 91精品中文字幕| 久久精品亚洲精品国产欧美kt∨| 国产日韩欧美精品在线观看| 亚洲成av人片在线观看www| 中文字幕日韩电影| 欧美一区二区三区不卡视频| 成人免费高清在线| 欧美日韩激情四射| 国产美女亚洲精品7777| 精品国产一区av| 波多野结衣一区二区在线| 不卡欧美aaaaa| 日韩欧美视频免费在线观看| 国产视频一区二区在线播放| 日韩一级黄色av| 国产一区二区小视频| 中文av一区二区| 亚洲无吗一区二区三区| 欧美精品尤物在线观看| 国产精品精品一区二区三区午夜版 | 久久精品国产91精品亚洲| 中文字幕在线一| 中文天堂在线一区| 青青草原国产在线视频| 精品久久久久中文字幕小说 | 四虎影院在线免费播放| 久久久久久99久久久精品网站| 欧美三级一级片| 亚洲小说图片| 国产成人精品优优av| 国产精品免费播放| 欧美私模裸体表演在线观看| www.涩涩爱| 国产乱理伦片在线观看夜一区 | gogo高清在线播放免费| 亚洲成人网久久久| 天天操天天爽天天干| 91视频91自| 国产又黄又猛视频| 欧美综合在线视频观看| 国产精品综合网站| 二区三区四区高清视频在线观看| 91精品国产色综合久久ai换脸| 欧美日韩在线视频免费播放| 成人白浆超碰人人人人| 国产1区2区在线| 欧美日韩激情| 91精品国产高清久久久久久91裸体| 色呦呦在线视频| 日韩电视剧免费观看网站| 伊人中文字幕在线观看| 中文字幕在线一区二区三区| 日本黄色www| 精品成人一区| 日韩欧美亚洲日产国| av日韩久久| 国内精品久久久久久久| 国产青青草在线| 777xxx欧美| 91porny在线| 国产精品电影院| 国产成人精品无码片区在线| 日韩成人伦理电影在线观看| 日本a级片在线观看| 日韩成人一级| 国产精品永久免费| av最新在线| 久久精品视频在线观看| 国产又爽又黄网站亚洲视频123| 欧美在线|欧美| 国产无码精品视频| 国产精品丝袜黑色高跟| www国产视频| 麻豆精品视频在线| 国产精品后入内射日本在线观看| 99久久99久久精品国产片果冰| 国产伦精品一区二区三区照片91| 国产亚洲人成a在线v网站| 久久久久久97| 在线观看的av| 日韩精品一二三四区| 国产视频在线一区| 在线观看视频欧美| 国产精品99精品无码视| 中文字幕亚洲在| 中文字幕在线1| 成人免费视频播放| 亚洲一区二区福利视频| 久久久青草婷婷精品综合日韩| 今天免费高清在线观看国语| 凹凸成人精品亚洲精品密奴| 成人动漫在线观看视频| 亚洲欧洲日韩精品在线| 日本久久中文字幕| sm久久捆绑调教精品一区| 久久这里有精品| 日本在线观看网站| 亚洲人成电影网| 五月天久久久久久| 91精品福利在线一区二区三区 | 最近高清中文在线字幕在线观看1| 美女久久久久久久久久久| 91大神在线网站| 亚洲性线免费观看视频成熟| 日本精品专区| 亚洲精品狠狠操| 刘亦菲久久免费一区二区| 日韩欧美国产wwwww| 国产又黄又猛又爽| 欧美日韩一区二区欧美激情| 欧美体内谢she精2性欧美| 精品国产91久久久| 欧美做受喷浆在线观看| 国产成人精品一区二区三区网站观看 | www.在线视频.com| 亚洲乱亚洲乱妇无码| 日本高清视频网站| 精品国免费一区二区三区| 国产高清免费观看| 91精品在线一区二区| 国产精品视频一二区| 欧美麻豆精品久久久久久| 中文字幕免费观看视频| 欧美日韩中文字幕精品| 波多野结衣一本一道| 欧美性猛交xxxx黑人交| 美女黄页在线观看| 欧美性淫爽ww久久久久无| 无码人妻丰满熟妇精品区| 91久久免费观看| 国产女优在线播放| 欧美日韩国产高清一区二区三区| 夜夜骚av一区二区三区| 欧美精品一卡两卡| 国产成人精品无码高潮| 欧美tk丨vk视频| 欧美 日韩 综合| 日韩成人av在线| 国产小视频在线| 在线日韩欧美视频| 麻豆影院在线观看| 欧美大片免费看| а√在线天堂官网| 欧美亚洲在线播放| 巨胸喷奶水www久久久免费动漫| 国产免费一区二区三区香蕉精| 91精品亚洲一区在线观看| 999视频在线观看| 欧美深夜视频| 手机看片福利永久国产日韩| 国产精品成久久久久| 国产高清不卡无码视频| 国产精品久久久久9999高清| 免费黄色一级网站| 精品午夜一区二区三区在线观看| 日本女人性视频| 成人精品高清在线| 卡一卡二卡三在线观看| 亚洲免费观看高清完整版在线观看 | 国产精品三级在线观看无码| 欧美韩国日本一区| 国产精品 欧美激情| 精品美女永久免费视频| 中文在线观看免费高清| 精品久久一二三区| 国产在线日本| 欧美风情在线观看| 韩国精品主播一区二区在线观看 | 91超碰caoporn97人人| 日韩一区精品| 国产91亚洲精品一区二区三区| 蜜桃精品噜噜噜成人av| a级网站在线观看| 羞羞答答国产精品www一本| 激情图片中文字幕| 91麻豆国产福利精品| 国产高潮流白浆| 色婷婷综合视频在线观看| 国产人妖一区二区三区| 亚洲欧美在线第一页| 日韩经典av| 国产精品稀缺呦系列在线| 欧美91在线| 成人午夜免费剧场| 男女男精品视频| 亚洲av无码一区二区三区网址| 中文字幕一区二区三区视频| 日韩精品1区2区| 精品免费视频一区二区| 日本中文字幕伦在线观看| 欧美孕妇孕交黑巨大网站| 涩爱av色老久久精品偷偷鲁| 亚洲精品一区国产精品| 国产精品资源| 在线看黄色的网站| 亚洲三级久久久| 中文字幕丰满人伦在线| 亚洲欧美一区二区激情| 女囚岛在线观看| 亚洲最大福利网| 91亚洲成人| 男人插女人下面免费视频| 26uuu国产一区二区三区| 国产污视频在线观看| 日韩一卡二卡三卡| 免费大片黄在线观看视频网站| 日韩av电影手机在线观看| 粉嫩一区二区三区四区公司1| av 日韩 人妻 黑人 综合 无码| 加勒比av一区二区| av片在线免费看| 欧美日韩一区二区三区在线| 福利在线午夜| 国产精品第七影院| 激情五月综合网| 天美星空大象mv在线观看视频| 久久久国产精品麻豆| 久久久成人免费视频| 亚洲精品视频免费| 天天综合av| 欧美一区二区三区在线播放 | 国产精品电影在线观看| 亚洲最大在线| 欧美黑人又粗又大又爽免费| 久久久不卡网国产精品一区| 久久精品久久久久久久| 亚洲图片制服诱惑| 日韩欧美一区二区三区在线观看| 日本免费高清不卡| 日本成人超碰在线观看| 国产一级淫片久久久片a级| 欧美色老头old∨ideo| 97最新国自产拍视频在线完整在线看| 国产精品久久久久久久久久免费| 波多野结衣在线播放一区| 中国黄色片一级| 亚洲精品久久7777| 噜噜噜久久,亚洲精品国产品| 亚州精品天堂中文字幕| 亚洲欧洲av| 色噜噜狠狠永久免费| 亚洲人成网站色在线观看| 亚洲av综合色区无码一二三区 | 成人高清免费观看| 国产毛片aaa| 亚洲视频在线免费看| 欧美成人毛片| 国产精品久久久久久久乖乖| 91在线视频播放| 成人小视频在线播放| 久久九九热免费视频| 超碰精品在线| 欧在线一二三四区| 综合久久久久综合| 蜜桃av中文字幕| 国产97色在线| 一精品久久久| 日韩少妇一区二区| 91国偷自产一区二区三区观看 | 97成人精品视频在线观看| 精品视频免费| 色婷婷狠狠18禁久久| 色综合欧美在线| 超碰在线caoporn| 久久精品国产美女| 久久国产欧美日韩精品| 国产精品6666| 影音先锋欧美精品| 99久久香蕉| 久久婷婷综合色| 亚洲成人资源在线| 日韩成人影视| 鲁片一区二区三区| 国产成人精品网址| 国产区在线观看视频|