一些关于dagger2的理解(二)
2016-05-17 14:14
381 查看
为什么要使用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();
}
}
@Module
public 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内各@provides
public interface BehaviourComponent {
void inject(Behaviour1Activity activity);//伴随的声明周期
}
相应的活动类代码:
好了,到这里两组的代码都实现了一样的简单功能,他们都没有需要new在活动中生成实例,就简单来说,它们的差距是很小的;如果假使按这两种方式,项目的规模往大走,那么dagger2的优势就会出来:哥是逻辑相关的,而静态加接口或越来越复杂(这个复杂更多的是量上,不一定是逻辑上),还有,他们两者的开销也是不一样的,Dagger2只有在生命周期开始的时候才会出现,周期结束时也消亡;而像静态加接口一样将实例一直存起来等待调用。
点击下载上面的Demo
如果这个时候问:为什么解耦或者为什么需要少几个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();
}
}
@Module
public 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内各@provides
public 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
相关文章推荐
- git开源库——视图控件——左侧抽屉侧边栏
- iOS雷达图 iOS RadarChart实现
- JavaScript 设置、读取Cookie
- 推荐系统概论
- 【第十二章】零配置 之 12.1 概述 ——跟我学spring3
- 【bug记录】mysql5.7.9-win64 的3534问题
- 跟我学机器视觉-HALCON学习例程中文详解-FUZZY检测用于开关引脚测量
- PAT乙级—1029. 旧键盘(20)-native
- 英伟达GPU 嵌入式开发平台
- [转发]Oauth 1.0 1.0a 和 2.0 的之间的区别有哪些?
- Flask(4)-Web表单
- 随想 -- SaaS项目中问题的发现和解决
- HDU 1060 Leftmost Digit
- 软件开发必备之-设计原则
- 飛飛(四十四)春哥来啦!
- 跟我学机器视觉-HALCON学习例程中文详解-IC引脚测量
- consul笔记
- IBM X3650 服务器更换内存的过程记录
- eaccelerator+PHP5.4导致smarty更新模板500报错
- Android Telephony 框架分析