亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

目錄
When a Switch Statement Becomes a Code Smell
Common Anti-Pattern Example
Refactoring Strategies
1. Use Strategy Pattern with a Factory
2. Replace with Class-Based Dispatching (Polymorphism)
3. Use a Map with Closures (for Simple Cases)
Bonus: Use Enum with Match (PHP 8 )
Bottom Line
首頁 後端開發(fā) php教程 您的php開關(guān)是否有代碼氣味?識別和重構(gòu)抗模式

您的php開關(guān)是否有代碼氣味?識別和重構(gòu)抗模式

Aug 02, 2025 am 08:00 AM
PHP switch Statement

是的,PHP中的switch語句本身不是代碼異味,但當(dāng)它在多個文件中重複、包含過多分支、與業(yè)務(wù)邏輯緊耦合、違反單一職責(zé)原則或基於對像類型進行判斷時,就會成為反模式;1. 使用策略模式加工廠:定義處理接口和具體類,通過工廠映射類型到處理器,新增類型只需註冊無需修改現(xiàn)有代碼;2. 使用基於類的分發(fā)(多態(tài)):讓對象自身決定行為,通過繼承抽像類實現(xiàn)具體邏輯,調(diào)用時直接執(zhí)行方法無需switch;3. 使用閉包映射(適用於簡單場景):用關(guān)聯(lián)數(shù)組存儲類型到閉包的映射,避免分支結(jié)構(gòu)但可測試性較低;4. PHP 8 可使用match表達式替代簡單switch,更安全且表達力強,但不能解決重複和耦合問題;根本目標(biāo)是避免switch隨業(yè)務(wù)增長而擴散,應(yīng)優(yōu)先採用多態(tài)、策略模式或工廠模式使代碼對擴展開放、對修改關(guān)閉,從而提升可維護性和可測試性。

Is Your PHP Switch a Code Smell? Identifying and Refactoring Anti-Patterns

Yes, a PHP switch statement isn't inherently a code smell — it's a valid control structure. But when used excessively, deeply nested, or repeated across your codebase, it can become an anti-pattern that harms maintainability, violates the Open/Closed Principle, and makes testing harder. Let's break down when a switch becomes problematic and how to refactor it effectively.

Is Your PHP Switch a Code Smell? Identifying and Refactoring Anti-Patterns

When a Switch Statement Becomes a Code Smell

A switch can be a red flag in the following situations:

  • Repeated across multiple files : You copy-paste the same switch logic in different places (eg, in a controller, service, and DTO).
  • Large number of cases : More than 5–6 cases often indicate a need for abstraction.
  • Tight coupling to business logic : The switch decides behavior based on type or status, but adding a new case requires modifying multiple switch blocks.
  • Violates Single Responsibility Principle : One class or method handles too many responsibilities via switch cases.
  • Used with object types or class names : eg, switch (get_class($object)) — this is a classic sign you need polymorphism.

These patterns make your code harder to extend and test. Every time you add a new type or status, you must hunt down every switch and update it — a maintenance nightmare.

Is Your PHP Switch a Code Smell? Identifying and Refactoring Anti-Patterns

Common Anti-Pattern Example

 class PaymentProcessor
{
    public function process($payment)
    {
        switch ($payment->type) {
            case 'credit_card':
                return $this->processCreditCard($payment);
            case 'paypal':
                return $this->processPayPal($payment);
            case 'bank_transfer':
                return $this->processBankTransfer($payment);
            default:
                throw new InvalidArgumentException('Unsupported payment type');
        }
    }
}

Now imagine this same logic is duplicated in validation, logging, or notification systems. One new payment method means updating multiple files — not scalable.

Refactoring Strategies

Here are several clean ways to eliminate switch anti-patterns:

Is Your PHP Switch a Code Smell? Identifying and Refactoring Anti-Patterns

1. Use Strategy Pattern with a Factory

Create an interface for the behavior and individual classes for each type.

 interface PaymentHandler
{
    public function handle($payment);
}

class CreditCardHandler implements PaymentHandler { /* ... */ }
class PayPalHandler implements PaymentHandler { /* ... */ }
class BankTransferHandler implements PaymentHandler { /* ... */ }

Then use a factory to map types to handlers:

 class PaymentHandlerFactory
{
    private $handlers;

    public function __construct()
    {
        $this->handlers = [
            'credit_card' => new CreditCardHandler(),
            'paypal' => new PayPalHandler(),
            'bank_transfer' => new BankTransferHandler(),
        ];
    }

    public function getHandler($type): PaymentHandler
    {
        if (!isset($this->handlers[$type])) {
            throw new InvalidArgumentException("No handler for $type");
        }
        return $this->handlers[$type];
    }
}

Now your processor becomes:

 class PaymentProcessor
{
    private $factory;

    public function __construct(PaymentHandlerFactory $factory)
    {
        $this->factory = $factory;
    }

    public function process($payment)
    {
        $handler = $this->factory->getHandler($payment->type);
        return $handler->handle($payment);
    }
}

Adding a new payment type? Just create a new handler and register it — no switch to modify.

2. Replace with Class-Based Dispatching (Polymorphism)

Instead of checking a type string, let the object itself define its behavior.

 abstract class Payment
{
    abstract public function process();
}

class CreditCardPayment extends Payment { /* ... */ }
class PayPalPayment extends Payment { /* ... */ }

Then your processor simply calls:

 $payment->process(); // No switch needed

This is the most elegant solution when you control the object hierarchy.

3. Use a Map with Closures (for Simple Cases)

For lightweight logic, you can replace a switch with an associative array of closures:

 $handlers = [
    'credit_card' => fn($p) => $this->processCreditCard($p),
    'paypal' => fn($p) => $this->processPayPal($p),
];

if (!isset($handlers[$type])) {
    throw new InvalidArgumentException();
}

return $handlers[$type]($payment);

This keeps things simple and avoids branching logic, though it's less testable than full classes.

Bonus: Use Enum with Match (PHP 8 )

If you're on PHP 8 , consider using match instead of switch for value mapping — it's safer and more expressive:

 return match ($status) {
    'draft' => Color::Gray,
    'published' => Color::Green,
    'archived' => Color::Red,
    default => throw new InvalidArgumentException(),
};

But note: match is better syntax, not a design fix. It doesn't solve the underlying coupling issue if you repeat it everywhere.

Bottom Line

A switch isn't evil — it's useful for simple branching or mapping known constants. But when it starts dictating behavior based on types or statuses across your app, it's time to refactor. Favor polymorphism, strategy patterns, or factories to make your code open for extension and closed for modification.

The goal isn't to eliminate every switch, but to avoid letting it become a maintenance trap. If you find yourself adding yet another case somewhere — ask: Could this be an object instead?

Basically, if your switch grows with your business logic, it's probably time to evolve it into something more maintainable.

以上是您的php開關(guān)是否有代碼氣味?識別和重構(gòu)抗模式的詳細內(nèi)容。更多資訊請關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本網(wǎng)站聲明
本文內(nèi)容由網(wǎng)友自願投稿,版權(quán)歸原作者所有。本站不承擔(dān)相應(yīng)的法律責(zé)任。如發(fā)現(xiàn)涉嫌抄襲或侵權(quán)的內(nèi)容,請聯(lián)絡(luò)admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅(qū)動的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Laravel 教程
1597
29
PHP教程
1488
72
解開性能:關(guān)於PHP開關(guān)與IF-Else的真相 解開性能:關(guān)於PHP開關(guān)與IF-Else的真相 Aug 02, 2025 pm 04:34 PM

Switchcanbeslightlyfasterthanif-elsewhencomparingasinglevariableagainstmultiplescalarvalues,especiallywithmanycasesorcontiguousintegersduetopossiblejumptableoptimization;2.If-elseisevaluatedsequentiallyandbettersuitedforcomplexconditionsinvolvingdiff

重構(gòu)神開關(guān):從復(fù)雜條件到清潔代碼 重構(gòu)神開關(guān):從復(fù)雜條件到清潔代碼 Aug 03, 2025 pm 04:01 PM

使用策略模式將基於類型或狀態(tài)的複雜條件邏輯替換為可擴展的策略類;2.通過多態(tài)消除類型檢查,讓每個對象自行實現(xiàn)其行為;3.用查找表(如字典)替代簡單的值到值或值到動作的映射;4.使用守衛(wèi)子句提前返回,減少嵌套層次;5.提取方法以命名和隔離條件邏輯。這些重構(gòu)方法將復(fù)雜的條件語句轉(zhuǎn)化為清晰、可維護的代碼,提升可讀性和可擴展性,且完全遵循開閉原則,最終實現(xiàn)乾淨(jìng)、表達力強的設(shè)計。

掌握控制流程:深入研究PHP的開關(guān)語句 掌握控制流程:深入研究PHP的開關(guān)語句 Aug 01, 2025 am 07:42 AM

PHP的switch語句通過一次表達式求值並進行鬆散比較來執(zhí)行匹配的代碼塊,常用於多分支控制流程;1.必須使用break防止意外的fall-through;2.switch使用鬆散比較(==),可能導(dǎo)致類型隱式轉(zhuǎn)換,需注意類型一致性;3.可通過省略break有意實現(xiàn)多個case的邏輯合併;4.適用於處理用戶角色、表單動作等離散值場景;5.PHP8引入的match表達式提供嚴(yán)格比較和表達式返回,是更安全的現(xiàn)代替代方案;6.簡單映射可用關(guān)聯(lián)數(shù)組結(jié)合null合併運算符實現(xiàn);正確使用switch可提升代

從切換到策略:與多態(tài)性替代方案分解邏輯 從切換到策略:與多態(tài)性替代方案分解邏輯 Aug 02, 2025 am 06:40 AM

當(dāng)看到基於類型或狀態(tài)的switch語句時,應(yīng)將其替換為多態(tài)性以提升代碼質(zhì)量。 1.通過定義抽象基類Order並讓每種訂單類型實現(xiàn)自己的process方法,將行為封裝在對象內(nèi)部。 2.客戶代碼直接調(diào)用order.process(),無需條件判斷。 3.新增訂單類型時只需新增類,無需修改現(xiàn)有代碼,符合開閉原則。 4.在跨切面邏輯或外部數(shù)據(jù)處理等場景下可保留switch,但應(yīng)考慮用工廠或策略模式封裝。 5.對於復(fù)雜行為,可引入策略模式,將算法獨立封裝並動態(tài)注入,實現(xiàn)解耦。最終獲得可擴展、易維護、高內(nèi)聚的代碼結(jié)構(gòu)

您的php開關(guān)是否有代碼氣味?識別和重構(gòu)抗模式 您的php開關(guān)是否有代碼氣味?識別和重構(gòu)抗模式 Aug 02, 2025 am 08:00 AM

是的,PHP中的switch語句本身不是代碼異味,但當(dāng)它在多個文件中重複、包含過多分支、與業(yè)務(wù)邏輯緊耦合、違反單一職責(zé)原則或基於對像類型進行判斷時,就會成為反模式;1.使用策略模式加工廠:定義處理接口和具體類,通過工廠映射類型到處理器,新增類型只需註冊無需修改現(xiàn)有代碼;2.使用基於類的分發(fā)(多態(tài)):讓對象自身決定行為,通過繼承抽像類實現(xiàn)具體邏輯,調(diào)用時直接執(zhí)行方法無需switch;3.使用閉包映射(適用於簡單場景):用關(guān)聯(lián)數(shù)組存儲類型到閉包的映射,避免分支結(jié)構(gòu)但可測試性較低;4.PHP8 可使用

提高可讀性:編寫可維護PHP開關(guān)塊的最佳實踐 提高可讀性:編寫可維護PHP開關(guān)塊的最佳實踐 Aug 04, 2025 pm 02:26 PM

Keepcasesfocusedbydelegatingcomplexlogictodedicatedfunctions;2.Alwaysincludeadefaultcasetohandleunexpectedvaluessafely;3.Avoidfall-throughlogicunlessintentionalandclearlycommented;4.Usereturninsteadofbreakinfunctionstoreducevariableusageandenableearl

Zend引擎內(nèi)部:PHP的Switch語句實際上是有效的 Zend引擎內(nèi)部:PHP的Switch語句實際上是有效的 Aug 03, 2025 am 12:55 AM

TheswitchstatementinPHPisnotinherentlyfasterthanif-elseif;1)theZendEnginetypicallycompilesswitchintolinearlycheckedopcodes,resultinginO(n)performanceformostcases;2)onlysequentialintegercaseswithnogapsmaytriggerO(1)jumptableoptimization,butthisisrarea

高級PHP開關(guān)技術(shù)您可能不使用 高級PHP開關(guān)技術(shù)您可能不使用 Aug 04, 2025 am 05:45 AM

useswitch(true)forbooleanconditionStocreateAcleanConconcontitionAlrouter.2.comBinesWitchWithIn_Array()

See all articles