一些关于dagger2的理解(二)

来源:互联网 发布:去向分布图用什么软件 编辑:程序博客网 时间:2024/05/18 20:10

        为什么要使用dagger2:首先的答案应该是解耦,可是它怎么就解耦了呢?再往直白了说:就是少几个new。

        如果这个时候问:为什么解耦或者为什么需要少几个new,我只能说换频道吧,对不起,我说不明白。

        我写的个人认为有助于理解Dagger2的上一篇博客,思路不是很清晰,也不是太好懂。

        按照上面的想法,其实我们可以用一个静态+接口的方式来实现,先说一些数据的结构:

       蓝色的是食物一组,Grass和Meat都继承Food接口,红色是动物一组Sheep和Tiger都继承Animal接口;

        Animal代码:

public interface Animal {    String printName();//给动物定义一个统一的方法}
        Tigger代码:

public class Tiger implements Animal{    private  String name = "老虎";    @Override    public String printName() {        return name;    }}
        Sheep代码:

public class Sheep implements Animal{    private String name = "羊";    @Override    public String printName() {        return name;    }}
        Food接口:

public interface Food {    String printType();}
        Grass代码:

public class Grass implements Food{    private String type = "肉";    @Override    public String printType() {        return type;    }}

        Meat代码:

public class Meat implements Food{    private String type = "肉";    @Override    public String printType() {        return type;    }}

        为以上的数据写一个静态方法的提供类:DataProvide.class代码

public class DataProvide {    public static Animal getAnimal(){        return new Sheep();    }    public static Food getFood(){        return new Meat();    }}
        这样,我们可以的Activity就可以这样写了:

public class Behaviour2Activity extends AppCompatActivity{    //这里不再需要new,需要改的时候去DataProvide处理就好了    Animal animal = DataProvide.getAnimal();    Food food = DataProvide.getFood();    Button btnShow;    TextView txtRelation;    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_behaviour2);        setTitle("普通方式");        btnShow = (Button) findViewById(R.id.btn_show);        txtRelation = (TextView) findViewById(R.id.txt_relation);        btnShow.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                txtRelation.setText("动物:"+animal.printName()+"      食物:" + food.printType());            }        });    }}
        到这里,我们可以算是勉强做到了不在去new一个个对象,在一个统一的地方进行类似配置的处理,但是这样有个很大的缺点:如果有大量的实例。。。而且还有不同的实例。。。。


==========================================请问你是谁?==================================

==========================================我是分割线!==================================

==========================================好巧,我也是==================================


        接下来是Dagger2的写法:

        首先是@module类

@Module //@module声明这个类是携带实体的组件,一个“容器”public class BehaviourModule {    @Named("A") //相同返回值类型时的区别符号    @Provides  //@provides声明以下的类型将被提供出去    public Animal getAnimal(){        return new Tiger();    }    @Provides //同上    public Food getFood(){        return new Meat();    }}

@Modulepublic class ArgModule {    private String str;    public ArgModule(String str){        this.str = str;    }    @Named("B")    @Provides    public Animal getArgAnimal(){        return new Animal() {            @Override            public String printName() {                return str;            }        };    }}


        接下来是@Component接口:

@Component(modules={BehaviourModule.class, ArgModule.class}) //添加组件,使用Module内各@providespublic interface BehaviourComponent {    void inject(Behaviour1Activity activity);//伴随的声明周期}

        相应的活动类代码:
public class Behaviour1Activity extends AppCompatActivity{    @Named("A")// 使用同样标记“A”的对象    @Inject //可以理解为该标记从DaggerBehaviourComponent中拿数据    Animal animal;    @Inject //因为只有一个,不需要@Named标记    Food food;    Button btnShow;    TextView txtRelation;    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_behaviour1);        setTitle("Dagger2方式");        DaggerBehaviourComponent                .builder()                .argModule(new ArgModule("猫"))                .build()                .inject(this);        btnShow = (Button) findViewById(R.id.btn_show);        txtRelation = (TextView) findViewById(R.id.txt_relation);        btnShow.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                txtRelation.setText("动物:"+animal.printName()+"      食物:" + food.printType());            }        });    }}


        好了,到这里两组的代码都实现了一样的简单功能,他们都没有需要new在活动中生成实例,就简单来说,它们的差距是很小的;如果假使按这两种方式,项目的规模往大走,那么dagger2的优势就会出来:哥是逻辑相关的,而静态加接口或越来越复杂(这个复杂更多的是量上,不一定是逻辑上),还有,他们两者的开销也是不一样的,Dagger2只有在生命周期开始的时候才会出现,周期结束时也消亡;而像静态加接口一样将实例一直存起来等待调用。

        点击下载上面的Demo








0 0