利用单一职责原则、接口隔离原则和单例模式对代码进行优化

本文针对一个具体的MainActivity进行了代码优化,通过引入设计模式如单一职责原则和接口隔离原则,以及使用单例模式,将复杂的类加载和方法调用过程封装到独立的服务类中,提高了代码的可读性和可维护性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

待优化的代码见上个博客:https://blog.youkuaiyun.com/wangning13ji/article/details/85064184

本文针对Test4里的MainActivity进行优化。

优化前:MainActivity.java

package com.test4.w00425655.test4;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import android.widget.Toast;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class MainActivity extends AppCompatActivity {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        final TextView mTextview = (TextView) findViewById(R.id.textview);

        try {
            //获取UID,验证是否相同
            PackageManager pm = getPackageManager();
            ApplicationInfo ai = pm.getApplicationInfo("com.test4.w00425655.test4", 0);
            Toast.makeText(MainActivity.this, Integer.toString(ai.uid,10), Toast.LENGTH_SHORT).show();
            mTextview.setText(Integer.toString(ai.uid,10));
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }


        Context context = null;
        try {
            context = this.createPackageContext("com.test5.w00425655.test5",CONTEXT_INCLUDE_CODE|Context.CONTEXT_IGNORE_SECURITY);

        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        final Context finalContext = context;
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                Class clazz = null;
                Object object = null;
                try {
                    //加载Test4的类和函数
                    clazz = finalContext.getClassLoader().loadClass("com.test5.w00425655.test5.MainActivity");
                    object = clazz.newInstance();
                    Method method = clazz.getDeclaredMethod("getString",String.class);
                    mTextview.setText((String)method.invoke(object,"cccccccccc"));
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }


                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {

            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

各位看官可以看到,优化前该Activity毫无设计模式和原则可言,是不是闻到了代码腐朽的味道,看到这样的代码是不是没有了继续写下去的勇气啦。没关系,接下来,我们将对它进行一次人生的洗礼,让它的价值得到完美的升华。

我们会利用单一职责原则,把加载类和调用方法的函数抽离出来封装一个类,该类只负责动态加载类,不进行其他操作。接着还需要利用接口隔离原则,把该类抽象成一个接口,这样,我们暴露给调用者的只有接口,不会有具体的实现,看起来是不是更加清晰明了了呢。最后,这个类我们只需要一个单例,不需要每次调用的时候都创建一个对象,节省了资源。下面就来看看最终的实现吧!duang~

抽象的接口类LoadClassService.java
package com.test4.w00425655.test4;

import android.content.Context;

public interface LoadClassService {
    /*Test5提供给Test4的接口*/
    String getString(String str, Context context);
}

接口的实现LoadClassImpl.java

package com.test4.w00425655.test4;

import android.content.Context;
import android.content.pm.PackageManager;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import static android.content.Context.CONTEXT_INCLUDE_CODE;

public class LoadClassImpl implements LoadClassService {
    private volatile static LoadClassService sLoadClass = null;
    private LoadClassImpl (){
    };
    public static LoadClassService getLoadClass (){
        if (null == sLoadClass) {
            synchronized (LoadClassImpl.class) {
                if (null == sLoadClass) {
                    sLoadClass = new LoadClassImpl();
                }
            }
        }
        return sLoadClass;
    }
    @Override
    public String getString (String str,Context context) {
        Class clazz = null;
        Object object = null;
        try {
            //加载Test4的类和函数
            clazz = getClazz("com.test5.w00425655.test5","com.test5.w00425655.test5.MainActivity",context);
            object = clazz.newInstance();
            Method method = clazz.getDeclaredMethod("getString",String.class);
            return (String)method.invoke(object,str);
        }  catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return null;
    }

    private Class getClazz(String path, String className,Context context){

        Class clazz = null;
        try {
            //加载Test4的类
            clazz = context.getClassLoader().loadClass(className);
            return clazz;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }
}

MainActivity.java的调用:

package com.test4.w00425655.test4;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import android.widget.Toast;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class MainActivity extends AppCompatActivity {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        final TextView mTextview = (TextView) findViewById(R.id.textview);

        try {
            //获取UID,验证是否相同
            PackageManager pm = getPackageManager();
            ApplicationInfo ai = pm.getApplicationInfo("com.test4.w00425655.test4", 0);
            Toast.makeText(MainActivity.this, Integer.toString(ai.uid,10), Toast.LENGTH_SHORT).show();
            mTextview.setText(Integer.toString(ai.uid,10));
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        Context context = null;
        try {
            context = this.createPackageContext("com.test5.w00425655.test5",CONTEXT_INCLUDE_CODE|Context.CONTEXT_IGNORE_SECURITY);

        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        final Context finalContext = context;
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                LoadClassService loadClass = LoadClassImpl.getLoadClass();
                mTextview.setText(loadClass.getString("cccc", finalContext));


                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
    }



    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {

            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

这样我们的优化就这么简单的完成了,是不是更加清晰明了了呢。真棒~

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值