Java 關於策略模式+簡單工廠模式下的思考

導讀

  最近在作公司一個消息網關的服務,包括:短信、微信、郵件等,全部請求經過一個入口,方便接口的管理(記錄日誌、接口限流白名單啥的)。如何寫這個接口呢,還有爲了之後擴展,對接太短信、微信、公衆號的童鞋大概都瞭解,首先定義一個模板,而後後臺傳入json,替換模板中的值,而後發送。設計框架大概思路是這樣的java

  1. 第一層:經過策略模式,選擇出具體的發送類型,好比:短信、微信、郵件。。。。。
  2. 第二層:再次經過策略模式,選擇出具體的第三方平臺,好比短信平臺:阿里雲、騰訊雲、華爲雲。。。。。。
  3. 第三層:經過一個簡單的工廠,選擇出具體的模板,而後發送出去

  第一二層,之後可能會擴展出二、3家第三方平臺,使用策略模式仍是能夠接受的,可是到了第三層的話,可能會出現一二十個模板,這樣子的話,會出現一大堆if else等等(寫過簡單工廠的都清楚),而後本身手動封裝一個工具類,獲取一個類下的全部子類,而後經過一個字段建立對象,這裏我作了一個優化,找到的值,我會先放到一個Map中,第二次請求來的時候,先去Map中查詢下,是否有值,有值的話,直接調用,沒有值的話,纔會去從新找一遍,這樣子性能也獲得了提升json

項目結構

工具類

package com.ybchen.messagegateway;

import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName:TestMain
 * @Description:TODO
 * @Author:chenyb
 * @Date:2020/12/1 9:19 上午
 * @Versiion:1.0
 */
public class TestMain {
    public static void main(String[] args) throws Exception {
            System.out.println("接口實現類:");
            for (Class<?> c : getAllAssignedClass(AbsClassA.class)) {
                if (c.getName().contains("D")){
                    AbsClassA obj =(AbsClassA) c.newInstance();
                    obj.speak();
                }
                System.out.println(c.getName());
            }
            System.out.println("子類:");
            for (Class<?> c : getAllAssignedClass(AbsClassA.class)) {
                System.out.println(c.getName());
            }
    }

    /**
     *  獲取同一路徑下全部子類或接口實現類
     *  
     *  @param intf
     *  @return
     *  @throws IOException
     *  @throws ClassNotFoundException
     */
    public static List<Class<?>> getAllAssignedClass(Class<?> cls) throws Exception {
        List<Class<?>> classes = new ArrayList<>();
        for (Class<?> c : getClasses(cls)) {
            if (cls.isAssignableFrom(c) && !cls.equals(c)) {
                classes.add(c);
            }
        }
        return classes;
    }

    /**
     *  取得當前類路徑下的全部類
     *  
     *  @param cls
     *  @return
     *  @throws IOException
     *  @throws ClassNotFoundException
     */
    public static List<Class<?>> getClasses(Class<?> cls) throws Exception {
        String pk = cls.getPackage().getName();
        String path = pk.replace('.', '/');
        ClassLoader classloader = Thread.currentThread().getContextClassLoader();
        URL url = classloader.getResource(path);
        return getClasses(new File(url.getFile()), pk);
    }

    /**
     *  迭代查找類
     *  
     *  @param dir
     *  @param pk
     *  @return
     *  @throws ClassNotFoundException
     */
    private static List<Class<?>> getClasses(File dir, String pk) throws ClassNotFoundException {
        List<Class<?>> classes = new ArrayList<>();
        if (!dir.exists()) {
            return classes;
        }
        for (File f : dir.listFiles()) {
            if (f.isDirectory()) {
                classes.addAll(getClasses(f, pk + "." + f.getName()));
            }
            String name = f.getName();
            if (name.endsWith(".class")) {
                classes.add(Class.forName(pk + "." + name.substring(0, name.length() - 6)));
            }
        }
        return classes;
    }
}
package com.ybchen.messagegateway;

/**
 * @ClassName:AbsClassA
 * @Description:TODO
 * @Author:chenyb
 * @Date:2020/12/1 9:16 上午
 * @Versiion:1.0
 */
public abstract class AbsClassA {
    public abstract void speak();
}
AbsClassA
package com.ybchen.messagegateway;

/**
 * @ClassName:ClassB
 * @Description:TODO
 * @Author:chenyb
 * @Date:2020/12/1 9:16 上午
 * @Versiion:1.0
 */
public class ClassB extends AbsClassA {
    @Override
    public void speak() {
        System.out.println("BBBBBBB");
    }
}
ClassB
package com.ybchen.messagegateway;

/**
 * @ClassName:ClassC
 * @Description:TODO
 * @Author:chenyb
 * @Date:2020/12/1 9:16 上午
 * @Versiion:1.0
 */
public class ClassC extends AbsClassA{
    @Override
    public void speak() {
        System.out.println("CCC");
    }
}
ClassC
package com.ybchen.messagegateway.de;

import com.ybchen.messagegateway.AbsClassA;

/**
 * @ClassName:ClassD
 * @Description:TODO
 * @Author:chenyb
 * @Date:2020/12/1 9:17 上午
 * @Versiion:1.0
 */
public class ClassD extends AbsClassA {
    @Override
    public void speak() {
        System.out.println("ddd");
    }
}
ClassD
相關文章
相關標籤/搜索