一些关于dagger2的理解(二)

转自:http://blog.csdn.net/shareye1992/article/details/51435230

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

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

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

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

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

        Animal代码:

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

  1. public class Tiger implements Animal{  
  2.     private  String name = "老虎";  
  3.   
  4.     @Override  
  5.     public String printName() {  
  6.         return name;  
  7.     }  
  8. }  
        Sheep代码:

  1. public class Sheep implements Animal{  
  2.     private String name = "羊";  
  3.   
  4.     @Override  
  5.     public String printName() {  
  6.         return name;  
  7.     }  
  8. }  
        Food接口:

  1. public interface Food {  
  2.     String printType();  
  3. }  
        Grass代码:

  1. public class Grass implements Food{  
  2.     private String type = "肉";  
  3.   
  4.     @Override  
  5.     public String printType() {  
  6.         return type;  
  7.     }  
  8. }  

        Meat代码:

  1. public class Meat implements Food{  
  2.     private String type = "肉";  
  3.   
  4.     @Override  
  5.     public String printType() {  
  6.         return type;  
  7.     }  
  8. }  

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

  1. public class DataProvide {  
  2.     public static Animal getAnimal(){  
  3.         return new Sheep();  
  4.     }  
  5.     public static Food getFood(){  
  6.         return new Meat();  
  7.     }  
  8. }  
        这样,我们可以的Activity就可以这样写了:

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


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

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

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


        接下来是Dagger2的写法:

        首先是@module类

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

  1. @Module  
  2. public class ArgModule {  
  3.     private String str;  
  4.     public ArgModule(String str){  
  5.         this.str = str;  
  6.     }  
  7.     @Named("B")  
  8.     @Provides  
  9.     public Animal getArgAnimal(){  
  10.         return new Animal() {  
  11.             @Override  
  12.             public String printName() {  
  13.                 return str;  
  14.             }  
  15.         };  
  16.     }  
  17. }  


        接下来是@Component接口:

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

        相应的活动类代码:
  1. public class Behaviour1Activity extends AppCompatActivity{  
  2.     @Named("A")// 使用同样标记“A”的对象  
  3.     @Inject //可以理解为该标记从DaggerBehaviourComponent中拿数据  
  4.     Animal animal;  
  5.     @Inject //因为只有一个,不需要@Named标记  
  6.     Food food;  
  7.   
  8.     Button btnShow;  
  9.     TextView txtRelation;  
  10.     @Override  
  11.     protected void onCreate(@Nullable Bundle savedInstanceState) {  
  12.         super.onCreate(savedInstanceState);  
  13.         setContentView(R.layout.activity_behaviour1);  
  14.         setTitle("Dagger2方式");  
  15.         DaggerBehaviourComponent  
  16.                 .builder()  
  17.                 .argModule(new ArgModule("猫"))  
  18.                 .build()  
  19.                 .inject(this);  
  20.         btnShow = (Button) findViewById(R.id.btn_show);  
  21.         txtRelation = (TextView) findViewById(R.id.txt_relation);  
  22.         btnShow.setOnClickListener(new View.OnClickListener() {  
  23.             @Override  
  24.             public void onClick(View v) {  
  25.                 txtRelation.setText("动物:"+animal.printName()+"      食物:" + food.printType());  
  26.             }  
  27.         });  
  28.     }  
  29.   
  30. }  


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

        点击下载上面的Demo
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值