精品欧美一区二区三区在线观看 _久久久久国色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技術棧公眾號

残酷重口调教一区二区| 中文字幕在线免费观看视频| 精品一区二区三区视频在线观看| 久久久精品久久久| www.欧美com| 久草在线视频网站| 国产亚洲1区2区3区| 成人两性免费视频| 国产精久久久久久| 精品国产网站| 日韩美女一区二区三区四区| av片中文字幕| 九义人在线观看完整免费版电视剧| 国产盗摄女厕一区二区三区 | 久久不射影院| 国产视频一区在线观看| 91久色国产| 天天爽夜夜爽人人爽| 日韩精品一区二区三区免费观影| 欧美成人官网二区| 欧美成人福利在线观看| 大菠萝精品导航| 亚洲视频你懂的| 免费精品视频一区二区三区| 99热这里只有精品在线观看| 久久大逼视频| 欧美日韩国产成人在线| 五月婷婷欧美激情| 日韩成人午夜| 欧美成va人片在线观看| 一女二男3p波多野结衣| 天天综合av| 一区二区欧美视频| 国产精品av免费| 色av男人的天堂免费在线| 国产成人精品免费在线| 国产精品亚洲自拍| 成人免费视频国产免费| 一本色道久久综合| 欧美第一页在线| 亚洲一级生活片| 日本久久综合| 伊人久久大香线蕉av一区二区| 国产a级黄色片| 日韩三级不卡| 91麻豆精品国产91久久久更新时间| 亚洲国产精品久久久久爰色欲| 亚洲精品白浆| 亚洲卡通欧美制服中文| 制服诱惑一区| 日本三级在线播放完整版| 久久久久久久久久久久久夜| 精品国产免费久久久久久尖叫 | 国产精品自拍一区| 91网站免费看| 国产又大又黑又粗| 精品中文av资源站在线观看| 国产精品视频一区二区三区四| www.99re7.com| 亚洲视频一二| 国外成人在线播放| 日本在线观看视频网站| 亚洲精品1区2区| 欧美精品videos另类日本| 精品在线视频观看| 亚洲网站视频| 97超级碰在线看视频免费在线看| 日产电影一区二区三区| 亚洲乱码视频| 性欧美在线看片a免费观看| 欧美福利视频一区二区| 亚洲少妇一区| 欧美激情videos| 精品无码av在线| 在线亚洲免费| 国产精品成人久久久久| 中文字幕一区二区三区波野结| 免费人成黄页网站在线一区二区| 国产欧美精品va在线观看| 国产伦一区二区| 国产91富婆露脸刺激对白| 国产亚洲欧美另类一区二区三区| 婷婷色在线视频| 久久午夜羞羞影院免费观看| 午夜一区二区三区| 在线观看小视频| 偷拍日韩校园综合在线| 精品久久久噜噜噜噜久久图片 | 欧美综合欧美视频| 亚洲a级黄色片| 第四色在线一区二区| 精品亚洲一区二区三区在线播放 | 一区二区高清免费观看影视大全| 欧美又粗又长又爽做受| 成人国产二区| 欧美高清视频www夜色资源网| 337p日本欧洲亚洲大胆张筱雨| 国产厕拍一区| 最近更新的2019中文字幕| 亚洲国产精品久| 欧美一级一区| 亚洲www在线| 深夜福利在线看| √…a在线天堂一区| 国产a级片网站| 国产亚洲欧美日韩精品一区二区三区| 日韩欧美一级二级三级| 免费黄色在线视频| 亚洲欧美在线专区| 日本亚洲欧美成人| 成人1区2区3区| 久久久久国产精品厨房| 中文字幕精品在线播放| 欧美一级大片| 精品国产亚洲在线| 18啪啪污污免费网站| 99国产精品99久久久久久粉嫩| 国产精品欧美久久久| 三级网站在线看| 国产精品不卡一区| 欧美极品欧美精品欧美图片| 日韩在线精品强乱中文字幕| 一区二区三区视频在线| 日韩av一区二区在线播放| 韩国成人精品a∨在线观看| 久久免费看av| 黄色大片在线| 这里是久久伊人| 国产7777777| 久久xxxx精品视频| 久久国产主播精品| 欧美韩日亚洲| 欧美一级二级在线观看| 91精品久久久久久久久久久久| 亚洲黄色免费| 99在线看视频| 国产乱色在线观看| 欧美日韩国产影片| 永久免费av无码网站性色av| 亚洲影院免费| 国产亚洲欧美另类一区二区三区| 日本在线视频www鲁啊鲁| 在线成人高清不卡| 国产精品麻豆一区| 欧美a一区二区| 日本一区高清在线视频| 日韩性xxx| 亚洲免费视频一区二区| 中文字幕亚洲精品在线| 成人黄色av电影| 99在线免费视频观看| 伊人精品综合| 欧美激情一区二区久久久| 国产乱淫av片免费| 亚洲男人的天堂在线观看| 91网址在线观看精品| 日韩久久视频| 国产日韩欧美视频在线| 男人在线资源站| 欧美日韩小视频| 青花影视在线观看免费高清| 另类的小说在线视频另类成人小视频在线| 日韩国产欧美一区| 国产精品4hu.www| 色妞一区二区三区| 国产特级aaaaaa大片| 有码一区二区三区| 怡红院一区二区| 午夜影院日韩| 日本一区二区三不卡| 久久婷婷五月综合色丁香| 日韩中文字幕网站| 国产黄频在线观看| 午夜精品一区二区三区电影天堂| 国产麻豆剧传媒精品国产av| 香蕉久久夜色精品| 日韩精品另类天天更新| 日韩电影精品| 欧美激情在线一区| 你懂的在线观看| 精品视频全国免费看| 国产97免费视频| hitomi一区二区三区精品| 漂亮人妻被中出中文字幕| 成人免费a**址| 51国产成人精品午夜福中文下载| 国产拍在线视频| 亚洲天堂成人在线视频| 在线免费av网| 亚洲福利一区二区三区| 一区二区三区免费在线观看视频 | 一区二区三区日韩| 欧美丰满少妇人妻精品| 六月丁香婷婷久久| 日本a视频在线观看| 欧美日韩在线观看视频小说| 亚洲xxxxx性| 婷婷综合六月| 久久躁日日躁aaaaxxxx| 日本福利片在线| 欧美丰满嫩嫩电影| 圆产精品久久久久久久久久久| 国产欧美va欧美不卡在线| 日本少妇激三级做爰在线| 亚洲男女自偷自拍| 亚洲高潮无码久久| 精品av一区二区| 成人蜜桃视频| 欧美91在线|欧美| 555www成人网| 伊人春色在线观看| 在线亚洲午夜片av大片| 少妇一区二区三区四区| 91精品国产综合久久久久| 99精品在线播放| 樱花影视一区二区| 综合 欧美 亚洲日本| 97se亚洲国产综合自在线不卡| 999这里有精品| 日韩二区三区四区| 欧美大片在线播放| 国产专区一区| 一区二区日本| 欧美日韩国产传媒| 久久精品国产99精品国产亚洲性色| 警花av一区二区三区| 国产精品视频久久久| 成人免费看视频网站| 久久琪琪电影院| 色老头在线观看| 精品国产欧美一区二区五十路| 精品一二三区视频| 亚洲精品视频播放| 婷婷av一区二区三区| 亚洲精品一区在线观看| 精品国产伦一区二区三区| 欧美群妇大交群中文字幕| 懂色av中文字幕| 色婷婷国产精品久久包臀| 日产精品久久久久久久| 亚洲成人动漫在线观看| 久久精品免费在线| 亚洲综合成人在线| 国产精品theporn动漫| 一区二区三区国产| 欧美被狂躁喷白浆精品| 伊人婷婷欧美激情| 久久精品www人人爽人人| 亚洲猫色日本管| 婷婷在线精品视频| 夜夜嗨av一区二区三区网页| 欧美成人777| 一区二区三区四区不卡在线| 欧美成人免费观看视频 | 亚洲欧洲高清在线| 免费成人av电影| 日韩精品一区二区视频| 午夜福利视频一区二区| 精品视频久久久久久久| 免费在线稳定资源站| 亚洲色图在线观看| 在线免费av电影| 久久久91精品国产| 日本在线观看大片免费视频| 欧美黄色成人网| 美女高潮在线观看| 国产成人精品久久二区二区91| 在线看欧美视频| 国产中文欧美精品| 日韩三级不卡| 麻豆成人av| 欧美日韩一区二区三区视频播放| 一区二区冒白浆视频| 激情六月综合| 国产麻花豆剧传媒精品mv在线| 日韩电影在线观看网站| 成人在线短视频| 91丝袜高跟美女视频| 亚洲精品成人av久久| 伊人开心综合网| 国产午夜精品久久久久| 欧美日本一区二区三区| 高清一区二区三区四区| 亚洲天堂色网站| av片在线观看| 日韩美女写真福利在线观看| 99精品国产九九国产精品| 国产精品高清一区二区三区| 精品免费av| www.日本三级| 日韩综合小视频| 日本精品一二三| 欧美国产一区视频在线观看| 欧美成人精品一区二区免费看片| 色婷婷av一区二区三区软件| 不卡av中文字幕| 最新亚洲国产精品| 美女av在线免费看| 99se婷婷在线视频观看| 精品久久电影| 久久久久久www| 久久国产精品区| 久久久久久久久免费看无码| 亚洲人成在线播放网站岛国| 亚洲天堂五月天| 精品999久久久| 毛片在线播放a| 国产激情久久久久| 国产精品18hdxxxⅹ在线| 亚洲一区二区在| 丝袜a∨在线一区二区三区不卡| 国内自拍偷拍视频| 国产精品网站在线观看| 999这里只有精品| 欧美精品tushy高清| 午夜国产在线观看| 欧美日韩国产二区| 成人国产精品一区二区免费麻豆 | 日韩污视频在线观看| 欧美欧美欧美欧美| 国产精品国产高清国产| 一级做a爰片久久毛片美女图片| 成人黄色动漫| 91免费版网站入口| 欧美aaaaaaaaaaaa| 国产免费一区二区三区视频| 欧美aaa在线| 国产123在线| 精品久久久免费| 六月丁香色婷婷| 欧美成人午夜激情在线| 澳门av一区二区三区| 久久伊人资源站| 影音先锋中文字幕一区二区| 亚洲精品久久久久久| 国产精品免费丝袜| 五月天婷婷导航| 亚洲美女黄色片| av女在线播放| 国产免费一区| 欧美.www| 一级黄色高清视频| 亚洲三级免费电影| 中文字幕91爱爱| 日日骚久久av| 丁香婷婷久久| 欧美日韩一区二区三区在线观看免 | 91精品人妻一区二区三区| 亚洲大片免费看| 天天躁日日躁狠狠躁喷水| 欧美高清videos高潮hd| 91午夜精品| 国产黄色片免费在线观看| 国产河南妇女毛片精品久久久 | 亚洲综合999| 国产精品一区二区av白丝下载 | 亚洲专区免费| 久久久久9999| 欧美中文字幕一区| 噜噜噜在线观看播放视频| 欧美在线视频一区二区| 日韩三区视频| 成人在线观看你懂的| 成人动漫一区二区在线| 精品一区在线视频| 亚洲久久久久久久久久| 男人最爱成人网| 在线观看成人一级片| 久久99精品国产麻豆婷婷| 动漫性做爰视频| 日韩欧美的一区二区| 国精产品一区一区三区mba下载| 99国产高清| 亚洲伦伦在线| 一区二区三区四区免费| 欧美日韩国产精品专区| 深夜福利视频在线免费观看| 国产欧美日韩91| 亚洲欧洲美洲一区二区三区| 国产精品无码在线| 一本一道波多野结衣一区二区| 日本中文字幕视频在线| 亚洲精品欧美日韩专区| 久久久久久久久久久妇女| 逼特逼视频在线观看| 日韩欧美在线字幕| 黄色av免费在线| 国产伦精品一区二区三区免费视频| 久久精品九九| 永久免费观看片现看| 5566中文字幕一区二区电影| 国产夫妻在线播放| 日韩中文字幕av在线| 丁香激情综合国产| 无码视频一区二区三区| 九九久久综合网站| 久久不卡国产精品一区二区| 天天爽夜夜爽视频| 黑人巨大精品欧美一区二区| 日本精品一区二区三区在线播放|