精华内容
下载资源
问答
  • 多个if怎么优化
    千次阅读
    2021-04-30 14:41:17

    在实际项目中相信大家都遇到过令人糟心的代码,一个方法一溜下来全是if else,还写满了业务逻辑,代码如下:

    public static void main(String[] args) {
            String name = "张三";
            if("张三".equals(name)){
                // 业务逻辑...
                System.out.println("我是张三");
            }else if("李四".equals(name)){
                // 业务逻辑...
                System.out.println("我是李四");
            }else if("王五".equals(name)){
                // 业务逻辑...
                System.out.println("我是王五");
            }else if("赵六".equals(name)){
                // 业务逻辑...
                System.out.println("我是赵六");
            }else if("钱七".equals(name)){
                // 业务逻辑...
                System.out.println("我是钱七");
            }else{
                // 业务逻辑...
            }
        }

    是不是很熟悉,哈哈哈~

    此时我们可以进行优化,巧用设计模式:策略模式+工厂方法

    首先,我们把每个条件逻辑代码块,抽象成一个公共的接口,我们根据每个逻辑条件,定义相对应的策略实现类,可得以下代码:

    定义接口:

    public interface NameService {
        String getName();
    }

    实现类:

    public class ZhansanName implements NameService {
        @Override
        public void getName() {
            // 张三业务逻辑...
            System.out.println("我是张三");
        }
    }
    public class LisiName implements NameService {
        @Override
        public void getName() {
            // 李四业务逻辑...
            System.out.println("我是李四");
        }
    }
    
    public class WangwuName implements NameService {
        @Override
        public void getName() {
            // 王五业务逻辑...
            System.out.println("我是王五");
        }
    }
    

    ......

    工厂类:

    public class NameServiceFactory {
        
        private static final Map<String, NameService> map = new HashMap<>();
    
        static {
            map.put("张三", new ZhansanName());
            map.put("李四", new LisiName());
            map.put("王五", new WangwuName());
            // ......
        }
    
        public static NameService getNameService(String name){
            return map.get(name);
        }
    
    }

    调用:

    public static void main(String[] args) {
            NameService nameService = NameServiceFactory.getNameService("张三");
            nameService.getName();
        }

     

    更多相关内容
  • 如何对多个if-else判断进行优化

    万次阅读 2020-11-16 16:07:04
    当我们遇到需要多个条件判断的业务操作时,最简单直接的办法就是用多个if-else判断,虽然能够实现,但当判断条件过多,甚至是多元判断时,我们的代码就会变得非常不好阅读和维护。 举个例子 这里也可以用switch if...

    如何对多个if-else判断进行优化

    当我们遇到需要多个条件判断的业务操作时,最简单直接的办法就是用多个if-else判断,虽然能够实现,但当判断条件过多,甚至是多元判断时,我们的代码就会变得非常不好阅读和维护。

    • 举个例子

    这里也可以用switch

    if(status === '1'){
          return '未审批'
        }else if(status === '2'){
          return '审批中'
        }else if(status === '3'){
          return '审批通过'
        }else if(status === '4'){
          return '审批退回'
        }else if(status === '5'){
          return '审批异常'
        }
    

    当判断越来越多的时候,优化的空间就来了,接下来和大家分享几种不同场景下关于if-else判断的优化技巧。

    1、使用Object对象

    适用于单层多个判断

    这是一种比较常见的方式,用Object对象把判断收集到一起

    const statusArr = {
          '1': '未审批',
          '2': '审批中',
          '3': '审批通过',
          '4': '审批退回',
          '5': '审批异常'
        }
        
    function getStatus(Num) {
          return statusArr[Num]
    }
        
    getStatus('1') //未审批
    

    这样是不是变得优雅一些了呢?可能看下来可能优化的效果没有非常显著,但别忘了,开发时也许不同的状态对应的是一个不同的方法,如果直接写在if-else中,代码就会变得又臭又长,举个例子对比一下

    代码仅作举例,没有实际意义

    if(status === '1'){
    	  //一些操作
          status = '2'
          return '未审批'
        }else if(status === '2'){
           //一些操作
          status = '3'
          return '审批中'
        }else if(status === '3'){
         //一些操作
          status = '4'
          return '审批通过'
        }else if(status === '4'){
         //一些操作
          status = '5'
          return '审批退回'
        }else if(status === '5'){
         //一些操作
          status = '0'
          return '审批异常'
        }
    

    怎么样,是不是已经眼花撩乱。同样优雅一下

    const statusArr = {
          '1': ()=>{
            //一些操作
            status = '2'
            return '未审批'
          },
          '2': ()=>{
            //一些操作
            status = '3'
            return '审批中'
          },
          '3': ()=>{
            //一些操作
            status = '4'
            return '审批通过'
          },
          '4': ()=>{
            //一些操作
            status = '5'
            return '审批退回'
          },
          '5': ()=>{
            //一些操作
            status = '0'
            return '审批异常'
          },
        }
        
    function getStatus(Num) {
          return statusArr[Num]
    }
        
    getStatus('1')()
    

    这样的话,将逻辑通过数据的形式维护起来,可读性更好。

    以上的方式也可以使用Map对象,相比于Object,Map对象的键就不仅仅只能是一个字符串,可以是任意值,包括函数、对象、基本类型,更加灵活。
    实际情况不多,不做举例。
    对于Map对象不了解的可以通过这篇博文简单了解。链接: Map对象的使用.

    2、通过字符串拼接的方式

    和上一种方式道理是一样,拼接后适合多元判断,例如不同的角色,通过字符串拼接的方式,在对象,或Map对象中进行查找相应的逻辑。

    举个例子:(比如当我们加上一个角色判断时)

    if(role === '打工人') {
    	if(status === '1'){
    	  //一些操作
        }else if(status === '2'){
           //一些操作
        }else if(status === '3'){
         //一些操作
        }else if(status === '4'){
         //一些操作
        }else if(status === '5'){
         //一些操作
        }
    } else if(role === '老板娘') {
    	if(status === '1'){
    	  //一些操作
        }else if(status === '2'){
           //一些操作
        }else if(status === '3'){
         //一些操作
        }else if(status === '4'){
         //一些操作
        }else if(status === '5'){
         //一些操作
        }
    }
    
    

    可以看到,当同一个方法,不同角色不同状态执行的操作不同时,代码将会变得冗长。
    优化的方法:同样使用一个对象收集这种不同的状态,但是由于多元的关系,将角色和状态进行字符串的拼接。

    let statusArr = {
          '打工人_1': ()=>{ \\一些操作 },
          '打工人_2': ()=>{ \\一些操作 },
          '打工人_3': ()=>{ \\一些操作 },
          '打工人_4': ()=>{ \\一些操作 },
          '打工人_5': ()=>{ \\一些操作 },
          '老板娘_1': ()=>{ \\一些操作 },
          '老板娘_2': ()=>{ \\一些操作 },
          '老板娘_3': ()=>{ \\一些操作 },
          '老板娘_4': ()=>{ \\一些操作 },
          '老板娘_5': ()=>{ \\一些操作 },
          
        }
    function getStatus(role,status) {
          return statusArr[`${role}_${status}`]
    }
    

    可以看到,改造之后,更加简明易读,

    不过个人认为这种拼接的方式始终不够规范,易读很可能只针对自己,对于接手的可能语义化还不够,下面介绍一种更好的方式。

    3、使用对象的方式存放在Map对象上

    上面这种方式之所以要拼接在一起,是因为对象的键需要是字符串的限制,如果使用Map对象,键就可以是一个对象、数组或者更多类型,方便了很多。

    let statusMap = new Map([
    	[{role: '打工人', status : '1'}, ()=>{ /*一些操作*/ }],
    	[{role: '打工人', status : '2'}, ()=>{ /*一些操作*/ }],
    	[{role: '打工人', status : '3'}, ()=>{ /*一些操作*/ }],
    	[{role: '打工人', status : '4'}, ()=>{ /*一些操作*/ }],
    	[{role: '打工人', status : '5'}, ()=>{ /*一些操作*/ }],
    	[{role: '老板娘', status : '1'}, ()=>{ /*一些操作*/ }],
    	[{role: '老板娘', status : '2'}, ()=>{ /*一些操作*/ }],
    	[{role: '老板娘', status : '3'}, ()=>{ /*一些操作*/ }],
    	[{role: '老板娘', status : '4'}, ()=>{ /*一些操作*/ }],
    	[{role: '老板娘', status : '5'}, ()=>{ /*一些操作*/ }],
    ])
    let getStatus = function(role,status) {
        statusMap.forEach((value,key)=>{
    	if(JSON.stringify(key) == JSON.stringify({role: role,status: status})){
    	value()
    	}
    })
    }
    getStatus('打工人','1') // 一些操作
    

    解释一下这段代码:
    将状态和角色组成对象放入Map对象中作为键名,将不同的方法作为对应的值。
    getStatus方法找到对应的操作并执行
    这里有一个小坑,由于键名是对象,所以查找Map对象时不能用Map.get()的方法,原因是由于对象的引用类型的问题,所以我用了这种方式转成字符串来比较。实测没有问题。

    以上几种都是基于处理逻辑和配置数据分离的优化方法,这种方法适用于一些不是逻辑不是太复杂的处理。

    对于一些复杂的处理逻辑,可以考虑使用责任链模式,这里简单介绍一下这种设计模式。

    4、责任链模式
    以上的几种方式,都是用穷举的方式在配置数据中查找到相对应的处理方法,而责任链模式就是将整个处理的逻辑改写成一条责任传递链,请求在这条链上传递,直到有一个对象处理这个请求。

    举个例子:

    在一个购物商城,在五一做了一个活动,所以图书类商品根据购买的金额依次做出以下折扣方案

    1、购买满199元,打9折

    2、购买满399元,打8折

    3、购买满599元以上,打7折;

    同样,用最简单的if-else判断写一下

    	if(price < 199){
          return '原价'
        }else if(199 <= price && price < 399){
          return '9折'
        }else if(399 <= price && price < 599){
          return '8折'
        }else if(599 <= price ){
          return '7折'
        }
    

    这里看起来并没有很复杂,但是如果在实际业务中,并不仅仅只需要返回一个折扣力度,可能还需要对活动商品、活动库存、是否使用优惠券等等进行计算,这样的话我们所有的逻辑就全部都写在这一个方法内的if判断语句内,可以想象,可读性是很差的。

    用责任链模式示范一下:

    第一个节点,原价的处理
    function BookHandler() {
    this.calcPrice = function( price ) {
    if ( 199 > price ) {
    console.log("原价是:"+ price);
    } else {
    this.successor.calcPrice( price );
    }
    }
    this.setSuccessor = function( _successor ) {
    this.successor = _successor;
    }
    }
    第二个节点,9折的处理
    function BookCalc9Handler( _successor ) {
    this.calcPrice = function( price ) {
    if ( 199 <= price && price < 399 ) {
    console.log("原价是:"+ price +";打9折后:" + (price * 0.9));
    } else {
    this.successor.calcPrice( price );
    }
    }
    this.setSuccessor = function( _successor ) {
    this.successor = _successor;
    }
    }
    第三个节点,8折的处理
    function BookCalc8Handler() {
    this.calcPrice = function( price ) {
    if ( 399 <= price && price < 599 ) {
    console.log("原价是:"+ price +";打8折后:" + (price * 0.8));
    } else {
    this.successor.calcPrice( price )
    }
    }
    this.setSuccessor = function( _successor ) {
    this.successor = _successor;
    }
    }
    最后,7折的处理
    function BookCalc7Handler() {
    this.calcPrice = function( price ) {
    if ( price >= 599 ) {
    console.log("原价是:"+ price +";打7折后:" + (price * 0.7));
    } else {
    this.successor.calcPrice( price )
    }
    }
    this.setSuccessor = function( _successor ) {
    this.successor = _successor;
    }
    }
     
    

    调用时:

    var price = 400;
    var bookHandler = new BookHandler();
    var bookCalc9Handler = new BookCalc9Handler();
    var bookCalc8Handler = new BookCalc8Handler();
    var bookCalc7Handler = new BookCalc7Handler();
    bookHandler.setSuccessor(bookCalc9Handler);
    bookCalc9Handler.setSuccessor(bookCalc8Handler);
    bookCalc8Handler.setSuccessor(bookCalc7Handler);
         将所有处理方法连成一条责任链,保证总有一个对象能够处理请求
    bookHandler.calcPrice(price);
    

    console.log的结果
    在这里插入图片描述

    如果不使用责任链链模式、根据当前价格要知道每一级打折信息,最后知道具体是那一层上打折才是符合当前价格的折扣。而使用这种模式,只需要知道当前的处理对象是否能够处理,如果不能处理,就传递给下一个对象,直到有一个对象最终处理,逻辑性更强。

    小结

    事实上,大部分业务需求都能使用最基本的if-else完成,只不过是简单和繁琐的问题,当我们遇到这类问题,不妨改变一下思路,将自己的代码优雅化,使用上数据配置或责任链模式,你会发现不仅仅是思路的扩展,代码的逻辑都清晰了不少,希望对各位有所帮助。

    展开全文
  • C++ - 优化多if-else-if 结构(一)

    千次阅读 2020-08-07 12:09:23
    因为最近做项目时遇到过这样的情景,总觉得在代码中写一大堆if-ele-if分支代码块不是很优雅,所以在此记录一下大量if-else-if代码块的优化情况。 1、level1:if-else-if分支(原始) 当程序中有大量的分支情况进行...

    在编程实践中总会遇到处理有大量分支情况,即根据不同的条件进行不同的处理。因为最近做项目时遇到过这样的情景,总觉得在代码中写一大堆if-ele-if分支代码块不是很优雅,所以在此记录一下大量if-else-if代码块的优化情况。

    1、Level1:if-else-if分支(原始)

    当程序中有大量的分支情况进行处理时,if-else-if分支结构总是大量使用,switch-case分支结构也是经常使用的,但是前者的应用面更广一些。

    下面就是应用if-else-if分支结构进行处理的情况:

    class NumSeq
    {
    public:
    	void func1(int);
    	void func2(int);
    	void func3(int);
    	//...
    
    	void run_seq(int);
    };
    
    void NumSeq::func1(int i_seq)
    {
    	cout << "调用函数 -- func1() " << "   传递参数: i_seq: " << i_seq << endl;
    }
    
    void NumSeq::func2(int i_seq)
    {
    	cout << "调用函数 -- func2() " << "   传递参数: i_seq: " << i_seq << endl;
    }
    
    void NumSeq::func3(int i_seq)
    {
    	cout << "调用函数 -- func3() " << "   传递参数: i_seq: " << i_seq << endl;
    }
    
    void NumSeq::run_seq(int i_seq)
    {
    	if (1== i_seq )
    	{
    		this->func1(i_seq);
    	}
    	else if (2== i_seq )
    	{
    		this->func2(i_seq);
    	}
    	else if (3== i_seq )
    	{
    		this->func3(i_seq);
    	}
    	else
    	{
    		cout << "Wrong i_seq.\n";
    	}
    }

     在成员函数run_seq()中,通过if-else-if对输入的i_seq进行判断,根据不同的值执行不同的函数。这是最常用的一种用法,但是,当i_seq的情况有很多,而对应的执行函数也有很多时,再使用if-else-if就会造成在run_seq()函数中堆积了大量的if-else-if代码块,看起来不是很优雅。

    2、Level2:使用类成员函数指针进行优化 - 1

    针对上述的问题,有一种解法是通过指向类成员函数的指针进行解决。首先介绍一下该指针。

    2.1 指向类成员函数的指针(Pointers to Class Member Functions)的声明

    pointer to member function(指向成员函数的指针),这种指针看起来和pointer to non-member function极为相似。两者皆需要指定其返回类型和参数列表。不过pointer to member function还需要指定它所指的究竟是哪一个class。例如以下定义方式:

    void (Foo::*pmf)(int) = 0;      //----------------------------------------------------------------------(1)

    上述声明方式,便是将pmf声明为一个指针,该指针指向一个类Foo的成员函数,后者的返回类型必须是void,并只能接收单个int类型的参数。pmf的初始值设置为了0,表示它目前并不指向任何成员函数。可以通过以下方式简化语法:

    typedef void (Foo::*Ptrtype)(int);    //----------------------------------------------------------------------(2)
    Ptrtype pmf = 0;

    上面的这种声明方式(2)和(1)中的声明完全等价。

    2.2 指向类成员函数的指针(Pointers to Class Member Functions)的赋值

    要对指向成员函数的指针进行赋值,首先要去的某个成员函数(member function)的地址,我们采用&取地址符,通过对函数名称应用&(address-of)运算符,即可取得成员函数的地址(这种取值方式和pointer to non-member function是有区别的,后者只需要用名称进行赋值即可)。但是需要注意的是,在函数名称之前必须先以class scope运算符加以限定,至于返回类型和参数列表皆可不必指明,如下所示:

    Ptrtype pmf = &Foo::func1;  //初始化pmf

     注意,函数体一定要定义!函数体一定要定义!函数体一定要定义!不然直接调用 &Foo::func2 语句会报错!

    同样如果是对pmf赋值,也应该采用上述方式:pmf = &Foo::func2;

    2.3 指向类成员函数的指针(Pointers to Class Member Functions)的使用

    pointer to member function 和 pointer to non-member function 在使用时的一个不同点是,前者必须通过同一类的对象加以调用,而对象便是此member function内的this指针所指之物,并且语法上也有些许不同,如下所示:

    Foo foo;
    Ptrtype pmf = &Foo::func1;

    为了通过foo调用pmf,可以这样写:

    (foo.*pmf)(i_num);  //和常规调用成员函数不同,在函数名之前必须添加*。这个*符号是个pointer to member selection运算符,系针对class object工作。而且必须为它加上外围小括号()才能正确工作。

    下面是针对pointer to class object的调用用法:

    Foo *p_foo = &foo;
    (p_foo->*pmf)(i_num);   //必须添加*和()

    2.4 使用 Pointers to Class Member Functions 优化

    使用 Pointers to Class Member Functions 对if-else-if进行优化,代码如下所示:

    class NumSequence 
    {
    public:
    	//定义了一种函数类型:指向成员变量,有一个Int型参数,返回void
    	typedef void (NumSequence::*Ptrtype)(int);
    
    	//_pmf可指向下列任何一个函数
    	void func1(int);
    	void func2(int);
    	void func3(int);
    	//...
    
    	void run_sequence(int);
    
    private:
    	Ptrtype _pmf;	//定义了一个 Ptrtype 类型的变量:_pmf,是一个指向类成员函数的指针
    };
    
    void NumSequence::func1(int i_seq)
    {
    	cout << "调用函数 -- func1() " << "   传递参数: i_seq: " << i_seq << endl;
    }
    
    void NumSequence::func2(int i_seq)
    {
    	cout << "调用函数 -- func2() " << "   传递参数: i_seq: " << i_seq << endl;
    }
    
    void NumSequence::func3(int i_seq)
    {
    	cout << "调用函数 -- func3() " << "   传递参数: i_seq: " << i_seq << endl;
    }
    
    void NumSequence::run_sequence(int index)
    {
    	switch (index)
    	{
    	case 1:
    		_pmf = &NumSequence::func1;	//类成员函数指针的赋值方式
    		break;
    	case 2:
    		_pmf = &NumSequence::func2;
    		break;
    	case 3:
    		_pmf = &NumSequence::func3;
    		break;
    	default:
    		_pmf = nullptr;
    		break;
    	}
    
    	if (_pmf)
    	{
    		//调用类成员指针的方式:(pC_reference->*pmf)(pars...) 或者 (C_reference.*pmf)(pars...)
    		(this->*_pmf)(index);
    	}
    }

    在上述代码中,通过run_sequence()函数,根据不同的index将不同的成员函数指针赋值给_pmf,然后再通过_pmf指针进行函数调用。

    但是上述代码并没有很好的优化if-else-if分支结构,只是一个引子,引出下面的优化方式。 

    3、Level3:使用类成员函数指针进行优化 - 2

    通过第2章节应该对指向成员函数的指针有了一个基本的了解,那怎么样才能更好的优化这个分支结构呢?

    首先思考一个问题,指向成员函数的指针虽然和普通的函数指针有些许不同,但它本质上还是一个指针,是指针,我们就可以把它存储起来,当有大量的指向成员函数的指针时,我们就用一个容器把它存储起来这样就可以根据需要提取不同的指针(该指针指向不同的成员函数),然后就可以通过该指针执行函数的调用。这样一想,就会发现它的使用和普通的函数指针没什么两样。

    所以为了更好的优化if-else-if分支结构,可以采用map容器进行存储,其中key用来存储index,也可以是其他的类型主要是为了区别不同地操作,value用来存储指向成员函数的指针。这样当我们获得一个key之后,就可以直接通过map获取对应的函数指针,就可以进行操作了。具体代码实现如下所示:

    #include <map>
    class advNumSequence
    {
    public:
    	//定义了一种函数类型:指向成员变量,有一个Int型参数,返回void
    	typedef void (advNumSequence::*Ptrtype)(int);
    
    	advNumSequence()
    	{
    		func_map[1] = &advNumSequence::adv_func1;
    		func_map[2] = &advNumSequence::adv_func2;
    		func_map[3] = &advNumSequence::adv_func3;
    	}
    
    	//_pmf可指向下列任何一个函数
    	void adv_func1(int);
    	void adv_func2(int);
    	void adv_func3(int);
    	//...
    
    	void run_sequence(int);
    
    private:
    	Ptrtype _pmf;	//定义了一个 Ptrtype 类型的变量:_pmf,是一个指向类成员函数的指针
    
    	map<int, Ptrtype> func_map;	//定义一个map。key为index,value为index对应的Ptrtype类型的类成员函数
    };
    
    void advNumSequence::adv_func1(int i_seq)
    {
    	cout << "调用函数 -- adv_func1() " << "   传递参数: i_seq: " << i_seq << endl;
    }
    
    void advNumSequence::adv_func2(int i_seq)
    {
    	cout << "调用函数 -- adv_func2() " << "   传递参数: i_seq: " << i_seq << endl;
    }
    
    void advNumSequence::adv_func3(int i_seq)
    {
    	cout << "调用函数 -- adv_func3() " << "   传递参数: i_seq: " << i_seq << endl;
    }
    
    void advNumSequence::run_sequence(int index)
    {
    	this->_pmf = this->func_map[index];	//取出对应的函数指针
    
    	(this->*_pmf)(index);
    }

    上述代码,在类的构造函数advNumSequence中 保存了成员函数的指针以及它们对应的key。这样在run_seqence()函数中,就可以直接通过key获取对应的函数指针,然后进行调用就可以了。

     

    4、Level4:使用设计模式进行优化

    C++ - 优化多if-else-if 结构(二):使用设计模式进行优化

    展开全文
  • 记一次多重if判断优化

    万次阅读 2020-01-22 11:37:41
    那可就完了,这么多个类型你要挨个判断不说,业务逻辑都写在了一个方法里,你不觉得这样耦合太紧了吗?你当然可以在订阅主题的方法里只写判断然后调用相应的方法,但是这么做。。总有点不好吧,如果你觉得没事...

    有时候写代码,你会发现越写越有劲,觉得越有趣,时间在不知不觉中流逝

    先看一下需求场景

    现在开始发挥你们的思路,如果要你们对接,你们会怎么做,写在一个方法里然后判断msgType的类型,然后做相应的事情? 那可就完了,这么多个类型你要挨个判断不说,业务逻辑都写在了一个方法里,你不觉得这样耦合太紧了吗?你当然可以在订阅主题的方法里只写判断然后调用相应的方法,但是这么做。。总有点不好吧,如果你觉得没事,那就没事,当然你可能还会说把多个方法订阅这一个主题,但是注意。在kafka中同一用户组不能订阅同一主题中的同一分区,那你会说弄多个分区不就好了么?恩。。这样问题更大,建议去系统的学习下kafka,那你会觉得那我每个方法订阅的不在同一用户组不就行了?是可以,但是你不觉得弄这么多方法订阅同一主题很别扭?假如主题名称改了,那你得改32个(当然主题名不可能随意更改)总之这样不利于维护,而且看起来很别扭

    在此之前我看过一些关于if优化的博客,大概也就是用策略模式加工厂模式代替

    当我看到我对接的kafka的消息中是通过msgType来判断的时候我就想到了,但是。。这么做弊端更大。看过的应该知道,对于每个情况都得创建一个类来实现一个特定的接口,,,那么我这里有32种情况,就得创建32个类。。这不疯了么

    当然聪明的我肯定不会这么干,那我会怎么做的呢?
    其实和上面那个策略模式类似或者说就是,只是我把“类”改成了“方法”
    你定义32个类来做,肯定疯了,但是32个方法不会呀。。所以我先写枚举,把每种情况都一一列出来

    在这里插入图片描述

    这里对应的就是那32种情况

    然后定义一个注解

    在这里插入图片描述

    这个注解实际上是用来标注,即我们扫描的时候方便一点,不然你怎么扫描,你怎么知道哪个类中的哪个方法是我们需要调用的。

    当然还有一个注解,是放在方法上的

    在这里插入图片描述

    里面有个值,就是我们刚刚定义的那个枚举类型,

    整体思路是这样,通过扫描有DeliveryKafkaConsumer该注解的类,然后再扫描有该类中有DeliveryKafkaConsumerMethod注解的方法,然后拿到DeliveryKafkaConsumerMethod注解的值,就知道当前这个方法是对应的哪种情况

    先来看下怎么使用

    创建一个类加上DeliveryKafkaConsumer注解

    在这里插入图片描述

    然后定义一个方法加上DeliveryKafkaConsumerMethod注解并指定枚举类型说明你要干什么
    在这里插入图片描述

    那么问题来了,我该怎么去调用这个方法,

    其实很简单具体实现

    @Component
    @Getter
    public class DeliveryEventConsumerParsing implements ApplicationContextAware {
    
        private final Map<String, Map<Object, Method>> map = Maps.newConcurrentMap();
    
        private static final ImmutableMap.Builder<String, String> BUILDER = new ImmutableMap.Builder<>();
    
        public static final ImmutableMap<String, String> INFO_MAP;
    
        static {
            MessageDeliveryEventConsumerEnum[] values = MessageDeliveryEventConsumerEnum.values();
            for (MessageDeliveryEventConsumerEnum message : values) {
                BUILDER.put(message.getId(), message.getName());
            }
            INFO_MAP = BUILDER.build();
        }
    
        private ApplicationContext applicationContext;
    
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            this.applicationContext = applicationContext;
            parsing();
        }
    
        private void parsing() {
            Map<String, Object> beanMap = applicationContext.getBeansWithAnnotation(DeliveryKafkaConsumer.class);
            Set<Map.Entry<String, Object>> entries = beanMap.entrySet();
            for (Map.Entry<String, Object> entry : entries) {
                Object obj = entry.getValue();
                scannerConsumerMethod(obj);
            }
        }
    
        private void scannerConsumerMethod(Object obj) {
            Class<?> clazz = obj.getClass();
            Method[] methods = clazz.getDeclaredMethods();
            for (Method method : methods) {
                addConsumerMethod(obj, method);
            }
    
        }
    
        private void addConsumerMethod(Object obj, Method method) {
            method.setAccessible(true);
            if (method.isAnnotationPresent(DeliveryKafkaConsumerMethod.class)) {
                DeliveryKafkaConsumerMethod kafka = method.getAnnotation(DeliveryKafkaConsumerMethod.class);
                Map<Object, Method> objMap = Maps.newHashMap();
                objMap.put(obj, method);
                map.put(kafka.value().getId(), objMap);
            }
        }
    }
    
    

    具体调用的方法,这个方法要订阅这个主题,记得要把DeliveryEventConsumerParsing这个类注入进来,因为我们的具体要调用的方法保存在这个类
    在这里插入图片描述

    这个订阅主题的方法,你们可以根据自己的需求的实现,我这里的匹配了一下方法的参数,如果目标方法的参数 我有或者我能从spring中拿到,那我就给他注入进去

    在这里插入图片描述

    自己灵活实现吧,

    注意:这里还有个注意的点 如果你当前类加了 @DeliveryKafkaConsumer这个注解和类中的方法刚好也加了 @DeliveryKafkaConsumerMethod这个注解,那么这时候该类就不能被动态代理,比如定时任务之类的 因为在spring boot中默认使用cglib的动态代理方式,cglib是通过继承重写方法实现的,如果你这个类被代理了,那么他就会重写你的方法,但是导致的问题就是你这个方法上的注解就丢了,扫描不到了

    如果你想在同一个类即使用@DeliveryKafkaConsumer和@DeliveryKafkaConsumerMethod注解,又想被动态代理,这里以定时任务为例

    在这里插入图片描述
    我这里是更新老师的信息,但是有个问题,先要去查询别的接口,并且这个接口要Token才能访问,如果我每次调用这个方法的时候都去重新获取Token 的话,显然是不合理的,
    我看了一下,接口返回的Token有效期为12个小时,那就好办了,我维护一个定时任务,定时来更新Token

    在这里插入图片描述

    在这里插入图片描述

    之前说过,不能写在同一类,但是我有想在一个类中维护,所以定义一个内部类就好了

    其实我之前尝试过很多解决方案,都可以解决,但是我还是觉得不太好,所以最后才想到这个内部类的写法

    这样的话就很方便我们写我们自己的业务逻辑了

    如果我们想监听新增老师的 方法
    只需和下面一样就行

    在这里插入图片描述

    这样写的主要目的就是把业务逻辑分开,有利于自己维护

    如有不对,欢迎指正

    在这里插入图片描述

    展开全文
  • 多个if else如何优化

    万次阅读 2018-10-19 09:38:48
    这段时间一直在整改代码圈复杂度,我们的要求是每函数方法圈复杂度不得大于5,以下是整改的部分截图 希望对整改代码的你有所提示或帮助,如果有更好的整改方法,还望您不吝赐教哦!  ...
  • 利用Java8优化if else

    万次阅读 2022-05-16 14:06:42
    前言 对接物联网设备,设备传递命令,然后根据命令操作不同的行为,最后返回。 现在问题是if else 太了,代码太... // 具体业务代码会比较,这里只是做一简单的代码框架例子。 return "开门"; } else if ("clo
  • 过多if-else分支的优化

    千次阅读 2020-11-30 10:56:52
    我想谈一谈这话题是因为我的上一篇博客在ITEye上有一些朋友回复,说if-else过多的分支可以使用switch或者责任链模式等等方式来优化。确实,这是一小问题,不过我们还是可以整理一下这小问题的重构方式。为什么...
  • js 多if情况下在优化

    千次阅读 2016-08-16 17:29:14
    var add_level={'5':1,'10':2,'12':3,'15':4}[add_step] || 0;
  • mysql if条件中的多个条件

    千次阅读 2021-04-19 04:27:49
    我试图将多个参数添加到if语句中.我正在尝试检查两队之间的比赛是否是联赛.SELECT visitor AS school, home AS temp, vl.leagueid AS vleague, hl.leagueid AS hleague,if(vl.leagueid = hl.leagueid, 1, 0) AS ...
  • Python中if多个条件怎么办

    千次阅读 2020-11-23 23:59:12
    Python中if多个条件怎么办python中if多个条件,可以使用and、or、elif关键字来连接。Python 编程中 if 语句用于控制程序的执行,基本形式为:(推荐:python视频教程)if 判断条件: 执行语句……else: 执行...
  • Python if多个条件怎么办

    千次阅读 2021-02-03 09:15:09
    Python中if多个条件的处理方法:python中if多个条件,可以使用and、or、elif关键字来连接,代码为【if name == 'zs' and age == 18:print('name: zs, age: 18')】。Python中if多个条件的处理方法:python中if...
  • 有很多if-else,该如何优化

    千次阅读 2021-01-14 00:25:05
    if 不满足条件时直接return掉,就不用写else了,这样可以减少if的深度对于你的例子了,如下:if (!tokenCheck.equals(token)) {obj.setStatus();obj.setMsg();return obj;}if (!isContinue) {obj.setStatus();obj....
  • Python中if多个条件处理方法

    千次阅读 2020-12-29 04:54:52
    在Python中,如果有多个条件做什么如果有多个条件如果在Python中,您可以使用,或者,elif关键字连接。Python编程的if语句是用来控制程序的执行。基本形式是:如果判断条件:执行语句\u2026\u2026:执行语句\u2026\u2026的...
  • if函数如何设置多个条件

    千次阅读 2021-05-22 03:15:11
    IF函数里面在条件不满足时可以使用“”显示空白,示例如下:①函数公式IF(条件判断,条件为真时执32313133353236313431303231363533e4b893e5b19e31333431343661行,条件为假时执行);②在A2单元格里面输入简单的公式...
  • 如何优化代码中的多层if嵌套

    千次阅读 2020-02-12 11:28:55
    前言 日常开发中经常要针对不同业务场景作出不同行为与...if(res.data.code===0){ //do something }else if(res.data.code===1002){ //do something }else if(res.data.code===1004){ //do something }else{ //do s...
  • 条件函数怎么用(if函数多个条件怎么用)2020-05-07 21:51:26共10个回答if函数可以嵌套七层,我简单举统计成绩中用到的一种写法:if(a1>=90,"优秀",if(a1>=60,"及格","不及格")其中a1要看你要分析的单元格的...
  • 关于c程序中多层嵌套结构的优化方法,在百度中找来找去,发现写这方面的文章不。下面就我个人总结出来的几方法,写出来,与大家分享。也希望看到这篇文章的人,要是有更好的方法,也在底下评论留言。您的一点...
  • java中的if与else语句if (条件一){} = 如果括号中条件一的正确,则执行大括号中的语句if (条件一){语句一} else{语句二} 如果条件一正确,执行语句一,否则执行语句二if (条件一){语句一} else if(条件二){语句二} ...
  • if函数怎么写多个条件?在办公的时候我们需要统计一些数据的时候都是需要到if函数来解决的,不过对于一些新手来说可能不是很清楚,游戏爱好者小编为大家整理了视频图文教程,一起来了解下吧。if函数写多个条件教程1...
  • Python中if多个条件应该如何处理

    千次阅读 2020-11-23 23:57:33
    Python中if多个条件应该如何处理发布时间:2020-04-24 14:55:11来源:亿速云阅读:323作者:小新Python中if多个条件应该如何处理?相信有很多人都不太了解,今天小编为了让大家更加了解Python中if多个条件的...
  • if函数多个条件并列

    千次阅读 2021-05-23 01:13:01
    16532、输入公式IF(AND(J1>0,K1>0),1,IF(AND(J1>0,K1<0),-1))。3、输入公式后,按回车键即可判断出J1大于0,K1大于0,就显示1。4、下拉复制公式J1大于0,K1小于0,就显示-1。例如在C1单元格输入如...
  • excel if函数多个条件怎么用教程

    千次阅读 2021-05-23 12:23:04
    Excel中的if函数,除了可以单个条件进行筛选,还可以有多个条件进行筛选,下面是由学习啦小编分享的excel if函数多个条件怎么用教程,希望对你有用。满足多个条件也可以分两种情况:1)同时满足多个条件;2)满足多个...
  • if条件中有多个判断条件,代码优化

    万次阅读 2018-05-11 16:26:19
    代码:优化后的代码:
  • 多个if与多个else if详解

    万次阅读 多人点赞 2017-11-16 10:43:59
    if与多个else if是分枝情况。只执行其中一条代码,if与多个if是并列情况,会顺序执行 如果是多个else if的话,只要第一个if条件成立,即使满足else if的条件也不会执行else if及else的内容
  • if语句中使用多个条件的优化

    千次阅读 2016-04-16 11:31:02
    if语句中使用多个条件的优化 一、使用and(&&)和or(||)运算符优化多条件if语句 例1:如何使用条件“degCent是否大于0,但又小于100?”。 方法一:使用嵌套的if语句 if(degCent0){ document.write("...
  • 在Java中多个 if-else 之间的执行顺序有什么区别呢? 对于 if-else 语句,它是 单条件双分支语句,即程序的执行流程是根据 一个条件来控制的; 如下代码演示了存在多个 if - else 时的执行顺序: int test11 = ...
  • Python中if多个条件怎么办python中if多个条件,可以使用and、or、elif关键字来连接。Python 编程中 if 语句用于控制程序的执行,基本形式为:(推荐:python视频教程)if 判断条件: 执行语句……else: 执行...
  • 多个if与多个else if的情况

    千次阅读 2018-08-08 09:50:09
    形式:  if ......if......if......else  if......else if......else if......... 总结:  如果是多个else if的话,只要第一个if条件成立,即使满足else if的... 如果是多个if的话,最后的else会执行;  el...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,885,632
精华内容 2,354,252
关键字:

多个if怎么优化