Verwenden Sie das Chain-of-Responsibility-Modell, um die Filterung der Codeverarbeitung zu transformieren

Szeneneinführung

Wenn die Anwendung aus dem Hintergrund in den Vordergrund tritt, springt sie zur Startseite, um die Bildschirmanzeige anzuzeigen, was ein relativ häufiges Szenario ist. Oft müssen wir einige Kontrollbedingungen hinzufügen, nicht in allen Fällen werden die Bildschirmanzeigen übersprungen, dann ist die Nutzererfahrung schlecht, sodass es eine Reihe von Filterbedingungen gibt.

Ursprünglicher Plan

Anfangs war es so:

  1. Bestimmen Sie, ob Sie von einer bestimmten Seite zurückblocken müssen
  2. Beurteilungskanal
  3. Kontrollieren Sie die Zeit- und Frequenzbegrenzung des Intervalls entsprechend dem Inhalt der Schnittstelle
       if (activity instanceof SplashActivity) {
            //启动页
            return;
        }
        if (activity instanceof LockScreenActivity) {
            //锁屏
            return;
        }
        if (activity instanceof AlcWidgetBaseConfigActivity) {
            //组件设置
            return;
        }
        if(AlcChannelUtil.isHuawei(this)){
            return;
        }
        String data = OnlineData.getInstance().getKey(activity, "go_splash_open", "");
        int status = 0;
        int oneDayMaxCount = 5;
        //120秒
        int offsetTime = 60;
        if (!TextUtils.isEmpty(data)) {
            try {
                JSONObject object = new JSONObject(data);
                status = object.optInt("isOpen");
                offsetTime = object.optInt("offsetTime");
                oneDayMaxCount = object.optInt("oneDayMaxCount");
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        boolean isOpen = status == 1;
        //转成毫秒
        offsetTime = offsetTime * 1000;
        if (isOpen) {
            //如果打开
            long lastSplashTime = (long) SPUtils.get(activity, "lastSplashTime", 0L);
            //并且时间间隔大于设置的时间间隔
            if ((System.currentTimeMillis() - lastSplashTime) > offsetTime) {
                //再判断次数是否达到上限
                //判断是否是今天
                int todayOpenCount = 0;
                if (TimeUtils.isSameDay(lastSplashTime)) {
                    todayOpenCount = (int) SPUtils.get(activity, "todayOpenCount", 0);
                }
                if (todayOpenCount < oneDayMaxCount) {
                    //小于这个次数,进入开屏页,保存这一次的时间,更新今天展开次数
                    SPUtils.put(activity, "lastSplashTime", System.currentTimeMillis());
                    todayOpenCount++;
                    SPUtils.put(activity, "todayOpenCount", todayOpenCount);
                    Intent goSplash = new Intent(activity, SplashActivity.class);
                    goSplash.putExtra("isFromOtherApp", true);
                    activity.startActivity(goSplash);
                }
            }
        }

Alles an einem Ort geschrieben, der Code ist aufgebläht und die Skalierbarkeit ist ebenfalls schlecht. Wenn Sie später Bedingungen hinzufügen oder löschen, werden Sie ihn hier direkt ändern. Es fühlt sich unangemessen an, daher habe ich darüber nachgedacht, das Chain-of-Responsibility-Modell zu verwenden, um ihn zu transformieren.

Verbessern

Grundklassen definieren

Definieren Sie zunächst drei Grundklassen, eine ist die Interceptor-Schnittstelle, eine ist die Kette, mit der alle Interceptors verbunden werden, und die andere ist die vom Interceptor verarbeitete Objekt-Bean.

public interface BaseSplashAdInterceptor {
    /**
     * 进行处理过滤,比如修改是否跳转广告、修改广告类型等
     *
     * @param adStatusBean
     */
    void doProcess(SplashAdStatusBean adStatusBean);
}

Kettenklasse

public class SplashAdChain {
    private List<BaseSplashAdInterceptor> mChains;

    /**
     * 添加拦截器
     * @param interceptor
     * @return
     */
    public SplashAdChain addInterceptor(BaseSplashAdInterceptor interceptor) {
        if (mChains == null) {
            mChains = new ArrayList<>();
        }
        mChains.add(interceptor);
        return this;
    }

    /**
     * 处理拦截操作
     * @param adStatusBean
     */
    public void doProcess(SplashAdStatusBean adStatusBean) {
        if (mChains != null) {
            for (BaseSplashAdInterceptor interceptor : mChains) {
                interceptor.doProcess(adStatusBean);
            }
        }
    }
}

Operationsobjektklasse:

public class SplashAdStatusBean implements Serializable {
    /**
     * 是否要跳转启动页广告
     */
    private boolean isNeedGoSplashAd;
    /**
     * 广告类型
     */
    private int splashAdType;
    /**
     * 从哪里来的
     */
    private Activity currentActivity;
    //...set和get方法 ,构造方法等
}

Interceptor einstellen

Stellen Sie dann den Abfangjäger gemäß den erforderlichen Bedingungen ein, zum Beispiel:

/**
 * 过滤Activity
 *
 * @author moore
 * @date 2019/8/5
 */
public class SplashAdActivityInterceptor implements BaseSplashAdInterceptor {

    @Override
    public void doProcess(SplashAdStatusBean adStatusBean) {
        if (adStatusBean.isNeedGoSplashAd()) {
            //如果需要跳转,再进行过滤
            Activity currentActivity = adStatusBean.getCurrentActivity();
            if (currentActivity == null) {
                adStatusBean.setNeedGoSplashAd(false);
                return;
            }
            if (currentActivity instanceof SplashActivity) {
                //启动页
                adStatusBean.setNeedGoSplashAd(false);
                return;
            }
            if (currentActivity instanceof LockScreenActivity) {
                //锁屏
                adStatusBean.setNeedGoSplashAd(false);
                return;
            }
            if (currentActivity instanceof AlcWidgetBaseConfigActivity) {
                //组件设置
                adStatusBean.setNeedGoSplashAd(false);
                return;
            }
        }
    }
}

Die anderen Bedingungen sind die gleichen, bewegen Sie ihn zum Abfangjäger, um zu operieren, und klassifizieren Sie sie. Wie das Steuern der Zeit, das Steuern der Häufigkeit, das Steuern der Art der Werbung und so weiter.

Verwenden Sie den Abfangjäger

Nachdem Sie diese Bedingungen definiert haben, können Sie sie verwenden, nach Bedarf hinzufügen und schließlich von jedem Interceptor ein Objekt verarbeiten lassen. Fahren Sie gemäß einigen Werten in diesem Objekt mit dem nächsten Schritt fort.

        //拦截过滤不需要跳转启动页的情况
        SplashAdStatusBean statusBean = new SplashAdStatusBean(true, 5, activity);
        SplashAdChain chain = new SplashAdChain()
                .addInterceptor(new SplashAdActivityInterceptor())
                .addInterceptor(new SplashAdChannelInterceptor())
                .addInterceptor(new SplashAdTimesInterceptor());
        chain.doProcess(statusBean);
        //拦截后如果需要跳转,那就跳转吧~~~
        if (statusBean.isNeedGoSplashAd()) {
            SPUtils.put(activity, "lastSplashTime", System.currentTimeMillis());
            SPUtils.put(activity, "todayOpenCount", (statusBean.getTodayOpenCount() + 1));
            Intent goSplash = new Intent(activity, SplashActivity.class);
            goSplash.putExtra("isFromOtherApp", true);
            activity.startActivity(goSplash);
        }

Fazit

Eine solche Unterteilung wird die Anzahl der Klassen erheblich erhöhen, aber wir können diese Filter- und Abfangoperationen deutlicher sehen und in Zukunft Änderungen deutlicher vornehmen, wodurch die Codekopplung verringert wird.

Ich denke du magst

Origin blog.csdn.net/lizebin_bin/article/details/98482096
Empfohlen
Rangfolge