简化嵌套的if语句 [英] simplify nested if statements

查看:61
本文介绍了简化嵌套的if语句的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在实现搜索功能,并且基于查询参数,我使用其他类进行搜索.

I'm implementing a search functionality and based on the query parameter i use a different class to search.

class Search { 

    public function getResults()
    {
        if (request('type') == 'thread') {
                $results = app(SearchThreads::class)->query();
        } elseif (request('type') == 'profile_post') {
                $results = app(SearchProfilePosts::class)->query();
        } elseif (request()->missing('type')) {
                $results = app(SearchAllPosts::class)->query();
     }

}

现在,当我想搜索线程时,我有以下代码.

Now when i want to search threads i have the following code.

class SearchThreads{

        public function query()
        {
            $searchQuery = request('q');
            $onlyTitle = request()->boolean('only_title');

            if (isset($searchQuery)) {
                if ($onlyTitle) {
                    $query = Thread::search($searchQuery);
                } else {
                    $query = Threads::search($searchQuery);
                }
            } else {
                if ($onlyTitle) {
                    $query = Activity::ofThreads();
                } else {
                    $query = Activity::ofThreadsAndReplies();
                }
            }
        }

}

解释代码.

如果用户输入搜索词( $ searchQuery ),则使用 Algolia 进行搜索,否则直接进行数据库查询.

If the user enters a search word ( $searchQuery) then use Algolia to search, otherwise make a database query directly.

  • 如果用户输入搜索词

  • If the user enters a search word

  1. 如果用户 选中了 onlyTitle 复选框
  2. ,则使用 Thread 索引.
  3. 如果用户选中 onlyTitle 复选框
  4. ,则使用线程索引.
  1. Use the Thread index if the user has checked the onlyTitle checkbox
  2. Use the Threads index if the user hasn't checked the onlyTitle checkbox

  • 如果用户未输入搜索词

  • If the user doesn't enter a search word

      如果用户选中 onlyTitle 复选框,则
    1. 获取所有线程
    2. 如果用户没有选中 onlyTitle 复选框
    3. ,则获取所有线程和答复
    1. Get all the threads if the user has checked the onlyTitle checkbox
    2. Get all the threads and replies if the user hasn't checked the onlyTitle checkbox

  • 是否有一种模式可以简化嵌套的if语句,还是应该为其中的情况创建一个单独的类

    Is there a pattern to simplify the nested if statements or should i just create a separate class for the cases where

    1. 用户输入了搜索词
    2. 用户未输入搜索词

    在每个类中检查用户是否已选中 onlyTitle 复选框

    And inside each of those classes to check if the user has checked the onlyTitle checkbox

    推荐答案

    我会将此代码重构为:

    保留请求参数以统一界面中的搜索方法.

    Leave the request parameter to unify the search methods in an interface.

    interface SearchInterface
    {
        public function search(\Illuminate\Http\Request $request);
    }
    
    class Search {
    
        protected $strategy;
    
        public function __construct($search)
        {
            $this->strategy = $search;
        }
    
        public function getResults(\Illuminate\Http\Request $request)
        {
            return $this->strategy->search($request);
        }
    }
    
    class SearchFactory
    {
        private \Illuminate\Contracts\Container\Container $container;
    
        public function __construct(\Illuminate\Contracts\Container\Container $container)
        {
            $this->container = $container;
        }
    
        public function algoliaFromRequest(\Illuminate\Http\Request  $request): Search
        {
            $type = $request['type'];
            $onlyTitle = $request->boolean('only_title');
            if ($type === 'thread' && !$onlyTitle) {
                return $this->container->get(Threads::class);
            }
    
            if ($type === 'profile_post' && !$onlyTitle) {
                return $this->container->get(ProfilePosts::class);
            }
    
            if (empty($type) && !$onlyTitle) {
                return $this->container->get(AllPosts::class);
            }
    
            if ($onlyTitle) {
                return $this->container->get(Thread::class);
            }
    
            throw new UnexpectedValueException();
        }
    
        public function fromRequest(\Illuminate\Http\Request $request): Search
        {
            if ($request->missing('q')) {
                return $this->databaseFromRequest($request);
            }
            return $this->algoliaFromRequest($request);
        }
    
        public function databaseFromRequest(\Illuminate\Http\Request $request): Search
        {
            $type = $request['type'];
            $onlyTitle = $request->boolean('only_title');
            if ($type === 'thread' && !$onlyTitle) {
                return $this->container->get(DatabaseSearchThreads::class);
            }
    
            if ($type === 'profile_post' && !$onlyTitle) {
                return $this->container->get(DatabaseSearchProfilePosts::class);
            }
    
            if ($type === 'thread' && $onlyTitle) {
                return $this->container->get(DatabaseSearchThread::class);
            }
    
            if ($request->missing('type')) {
                return $this->container->get(DatabaseSearchAllPosts::class);
            }
    
            throw new InvalidArgumentException();
        }
    }
    
    
    final class SearchController
    {
        private SearchFactory $factory;
    
        public function __construct(SearchFactory $factory)
        {
            $this->factory = $factory;
        }
    
        public function listResults(\Illuminate\Http\Request $request)
        {
            return $this->factory->fromRequest($request)->getResults($request);
        }
    }
    

    由此得出的结论是,不要将请求包含在构造函数中,这一点非常重要.这样,您可以在应用程序生命周期中创建实例而无需请求.这有利于缓存,可测试性和模块化.我也不喜欢应用程序和请求方法,因为它们会凭空获取变量,从而降低了可测试性和性能.

    The takeaway from this is it is very important to not involve the request in the constructors. This way you can create instances without a request in the application lifecycle. This is good for caching, testability and modularity. I also don't like the app and request methods as they pull variables out of thin air, reducing testability and performance.

    这篇关于简化嵌套的if语句的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆