抽象工厂模式 Abstract Factory Pattern

定义

抽象工厂模式 Abstract Factory Pattern:提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。

使用场景

  • 一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有类型的工厂模式都是重要的。
  • 系统中有多于一个的产品族,而每次只使用其中某一产品族。
  • 属于同一个产品族的产品将在一起使用,这一约束必须在系统的设计中体现出来。
  • 系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现。

UML 图

AbstractFactory:抽象工厂
ConcreteFactory:具体工厂
AbstractProduct:抽象产品
Product:具体产品

Read more   2016/2/1 posted in  Java

强引用、软引用、弱引用、虚引用

强引用 StrongReference

只要某个对象有强引用与之关联,JVM必定不会回收这个对象,即使在内存不足的情况下,JVM宁愿抛出OutOfMemory错误也不会回收这种对象

若需要 jvm 回收此对象,可以将对象复制为 null

Object o = new Object();   //  强引用  
o = null;     // 帮助垃圾收集器回收此对象  

但是如果这个o是全局的变量时,就需要在不用这个对象时赋值为null,因为强引用不会被垃圾回收。

Read more   2016/1/24 posted in  Java

VIM 技巧

VIM

代码选择

v:选择代码块
V:选择代码行
ctrl+V:多行选中模式 (esc 之后生效)

跳转

  • ):代码快跳转
  • ] :函数跳转
  • } :class 跳转
    ## 移动
  • hjkl
  • f/F: 查找字符
  • t/T: 同上,区别是停留前一个字符
  • gg/G: 文件开头/结尾
  • H/M/L:跳到当前屏幕的顶部/中间/底部。
  • ‘[ 跳到上一次被改变的文本的第一个字符
  • '. 跳到上一次文本被修改的地方
  • '' 跳回上一次跳转的地方
  • '^ 跳到插入模式最后一次结束的地方
    ## 编辑模式
  • x/X是删除当前光标下/光标前的一个字符
  • d/c/y是删除/修改/复制命令

diw, yiw, ciw, viw 删除(复制,改变,选中)光标所在单词
da”, ya”, ca”, va” 删除(复制,改变,选中)””号内所有文本,包括引号本身

  • * 向前查找当前光标下的单词
  • # 反方向查找当前光标下的单词
  • 我们在使用的过程中,会遇到这样的问题,分别在两个地方删除内容,然后需要分别粘贴,这样的情况就需要用到"ayy "ap这样的命令了,"ayy是把当前行复制到名字为a的寄存器中,"ap就是在这里粘帖a寄存器中的内容。
2016/1/10 posted in  Java

java 反射学习

概要

反射就是能够根据你给出类名实例化出一个实实在在的对象。所以,对象的实例化就不是写死的了,我们可以根据传入的类名不同,从而可以实例化出不同的对象。这种方式可以和工厂设计模式很好的结合,从而可以更加灵活的创建对象

测试用例

定义一个类

定义一个类,用反射来调用他的成员,方法,构造函数等

package com.example.xuyushi.reflecttest;

import android.util.Log;

/**
 * Created by xuyushi on 15/7/14.
 */
public class student {
    static final String TAG = "student";
    private int age;
    private String name;
    private String addresss;

    public student() {
        Log.d(TAG, "none parameter student constructor");
    }

    public student(int age, String name, String addresss) {
        this.age = age;
        this.name = name;
        this.addresss = addresss;
        Log.d(TAG, "3 parameters student constructor");

    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddresss() {
        return addresss;
    }

    public void setAddresss(String addresss) {
        this.addresss = addresss;
    }

    @Override
    public String toString() {
        return super.toString();
    }

    public void printMessage(int age,String name,String adress){
        Log.d(TAG, "name=" + name + ",age=" + age + ",adress=" + adress);
    }
}

测试用例

public class MainActivity extends Activity {
    static final String TAG = "student";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        testReflect();
    }

    private void testReflect() {
        try {
            /**
             * 1 反射出无参的构造方法并得到对象
             * 注意:
             *      1 在Class.forName()中应该传入含有包名的类全名
             *      2 newInstance()方法的本质是调用类的无参Public构造方法
             */
            String className1="com.example.xuyushi.reflecttest.student";
            Class clazz1=Class.forName(className1);
            Object object1=clazz1.newInstance();


            /**
             * 2 反射出带参数的构造方法并得到对象
             */
            String className2="com.example.xuyushi.reflecttest.student";
            Class clazz2=Class.forName(className2);
            Constructor constructor1=clazz2.getConstructor(int.class,String.class,String.class);
            Object object2=constructor1.newInstance(18,"zhangsan","beijing");
            Log.d(TAG, object2.toString());
            /**
             * 3 获取类的私有字段
             * 注意:
             *      获取共有字段应调用clazz3.getField(name)方法
             */
            String className3="com.example.xuyushi.reflecttest.student";
            Class clazz3=Class.forName(className3);
            Field ageField1=clazz3.getDeclaredField("age");
            Log.d(TAG,"ageField1=" + ageField1);

            /**
             * 4 获取和更改某个对象的私有字段
             *   即模拟get()和set()方法
             */
            String className4="com.example.xuyushi.reflecttest.student";
            Class clazz4=Class.forName(className4);
            Field ageField2=clazz4.getDeclaredField("age");
            Object object4=constructor1.newInstance(19,"wangwu","shanghai");
            //取消访问私有字段的合法性检查
            ageField2.setAccessible(true);
            //获取对象的私有字段
            Object ageObject4=ageField2.get(object4);
            Log.d(TAG, "ageObject4=" + ageObject4);

            //再更改对象的私有字段的值
            ageField2.set(object4, 27);
            //重新获得
            Object ageObject5=ageField2.get(object4);
            Log.d(TAG, "ageObject5=" + ageObject5);

            /**
             * 5 调用对象的带参数的方法
             */
            String className5="com.example.xuyushi.reflecttest.student";
            Class clazz5=Class.forName(className5);
            Method method=clazz5.getMethod("printMessage",int.class,String.class,String.class);
            Object object5=clazz5.newInstance();
            method.invoke(object5,50, "lisi","hangzhou");


        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @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);
    }
}

实际用例

开关移动流量需要用到sdk中的隐藏函数,需要利用到反射机制实现

public void toggleMobileData(Context context, boolean enabled) {
        ConnectivityManager conMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

        Class<?> conMgrClass = null; // ConnectivityManager类
        Field iConMgrField = null; // ConnectivityManager类中的字段
        Object iConMgr = null; // IConnectivityManager类的引用
        Class<?> iConMgrClass = null; // IConnectivityManager类
        Method setMobileDataEnabledMethod = null; // setMobileDataEnabled方法

        try {
            // 取得ConnectivityManager类
            conMgrClass = Class.forName(conMgr.getClass().getName());
            // 取得ConnectivityManager类中的对象mService
            iConMgrField = conMgrClass.getDeclaredField("mService");
            // 设置mService可访问
            iConMgrField.setAccessible(true);
            // 取得mService的实例化类IConnectivityManager
            iConMgr = iConMgrField.get(conMgr);
            // 取得IConnectivityManager类
            iConMgrClass = Class.forName(iConMgr.getClass().getName());
            // 取得IConnectivityManager类中的setMobileDataEnabled(boolean)方法
            setMobileDataEnabledMethod = iConMgrClass.getDeclaredMethod("setMobileDataEnabled", Boolean.TYPE);
            // 设置setMobileDataEnabled方法可访问
            setMobileDataEnabledMethod.setAccessible(true);
            // 调用setMobileDataEnabled方法
            setMobileDataEnabledMethod.invoke(iConMgr, enabled);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
2015/6/14 posted in  Java