高凝聚,低耦合-----箴言-----
内容简介:
反向控制(Inversion of Control,缩写为IoC),也称控制反转。是面向对象编程中的一种设计原则,可以用来降低计算机代码之间的耦合度。
通过反向控制,对象在被创建的时候,由一个调控系统内所有对象的外界实体将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。
面向对象的设计目的之一就是高凝聚,低耦合。反向控制作为一种设计原则,尽可能地实现低耦合的目的。
1. Android Framework的反向控制
在Android系统中,到处可以看到反向控制的体现。不夸张地说,反向控制是Android应用框架(Application Framework,即AF)魅力的源泉。其常见的实现有:
1) 继承(Inheritance)
---- 这与Template Method模式关系密切。
2)委托(Delegation)
---- 这与Observer模式密切相关。
反向控制是一种机制,其具体体检在继承和委托。而继承和委托,又可以在设计模式中找到具体的体现。这样一来,这些概念就和代码联系起来了。
在Android系统中,包括Framework层和Application,反向控制机制处处可见。
。这两种机制的具体体现,可以很容易对应到Template Method和Observer模式。反过来,通过对设计模式的运用,也能更加深刻体会到这些机制的真正含义。这样,除了更能活用Android之外,也能逐渐提升个人在程序设计,设计模式,架构方面的构建能力。同时,也更容易读懂别人的代码。
2. 复习:使用继承(Template Method模式来实现)
面向对象中,封装,继承,多态这些特性,都是一些逻辑概念,这些概念都可以有一些具体体现,例如:
封装:类和对象;
继承:在Template Method设计模式,很好的体现了继承这个概念。
多态:方法重载。
下面,先复习一下Java中的Template Method设计模式。
// Student.java
public class Student {
private String m_name;
private int m_credit;
Student(String na, int cr ){
m_name = na;
m_credit = cr;
}
public void print(){
System.out.println(m_name + ", " +String.valueOf(template_computeTuition()));
}
public float template_computeTuition() {
if (m_credit > 6) m_credit = 6;
return hook_getValue(m_credit) + 5000;
}
protected float hook_getValue(int credit){
return (credit -1) * 500;
}
}
// Graduate_Student.java
public class Graduate_Student extends Student{
Graduate_Student(String na, int cr ){
super(na, cr);
}
protected float hook_getValue(int credit){
return credit * 700;
}
}
// Undergraduate_Student.java
public class Undergraduate_Student extends Student {
Undergraduate_Student(String na, int cr ){
super(na, cr);
}
}
//测试主程序代码: JMain.java
public class JMain {
public static void main(String[] args) {
int credit = 5;
Graduate_Student mike = new Graduate_Student("Mike", 5);
mike.print();
Undergraduate_Student linda = new Undergraduate_Student("Linda", 7);
linda.print();
}
}
说明:
这是以Template Method设计模式来实现反向控制。
3.使用委托(即Observer设计模式来实现)
在Template Method设计模式中,hook method的具体实现是在子类中。使用委托时,则将hook method定义在独立的类中,如下述的HookClass:
//把hook method定义在独立的类中:
// HookClass.java
public class HookClass {
protected float getValue(int credit){
return (credit -1) * 500;
}
}
//template method委托HookClass类的实例去处理定制化(可变)部分:
// Student.java
public class Student {
private String m_name;
private int m_credit;
private HookClass hookObject = null;
Student(String na, int cr ){
m_name = na;
m_credit = cr;
}
public void setHook(HookClass hk){
hookObject = hk;
}
public void print(){
System.out.println(m_name + ", " +String.valueOf(template_computeTuition()));
}
public float template_computeTuition() {
if (m_credit > 6) m_credit = 6;
return hookObject.getValue(m_credit) + 5000;
}
}
//定义HookClass的子类:GraduateHook,并且让Student类的实例委托给GraduateHook子类的实例:
// Graduate_Student.java
public class Graduate_Student extends Student{
Graduate_Student(String na, int cr ){
super(na, cr);
setHook(new GraduateHook());
}
private static class GraduateHook extends HookClass{
@Override
protected float getValue(int credit){
return credit * 700;
}
}
}
// JMain.java
public class JMain {
public static void main(String[] args) {
int credit = 5;
Student mike = new Graduate_Student("Mike", credit);
mike.print();
}
}
说明:
这样一来,,Student类的template method 就调用了HookClass抽象类的getValue(),进而反向调用到GraduateHook类的getValue()方法。
4. Observer设计模式的Listener代码实现:
Observer设计模式又称为Listener模式,这样,大家理解了吧,不要说,没有用过Listener啊。
用Listener方式,上面的例程可以改写为:
// IListener.java
public interface IListener {
float getValue(int credit);
}
// Student.java
public class Student {
private String m_name;
private int m_credit;
private IListener plis = null;
Student(String na, int cr ){
m_name = na;
m_credit = cr;
}
public void setListener(IListener lis){
plis = lis;
}
public void print(){
System.out.println(m_name + ", " +String.valueOf(template_computeTuition()));
}
public float template_computeTuition() {
if (m_credit > 6) m_credit = 6;
return plis.getValue(m_credit) + 5000;
}
}
// Graduate_Student.java
public class Graduate_Student extends Student{
Graduate_Student(String na, int cr ){
super(na, cr);
setListener(new GraduateListener());
}
private static class GraduateListener implements IListener{
public float getValue(int credit) {
return credit * 700;
}
}
}
// JMain.java
public class JMain {
public static void main(String[] args) {
int credit = 5;
Student mike = new Graduate_Student("Mike", credit);
mike.print();
}
}
5. 欣赏Android中的Observer设计模式(用Listener实现):
程序范例代码:
package com.test.myapp.ui;
// MyMainActivity.java
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import com.test.myapp.ui.R;
public class MyMainActivity extends Activity {
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
Button btn = (Button) findViewById(R.id.button);
Button btn2 = (Button) findViewById(R.id.button2);
btn.setBackgroundResource(R.drawable.gray);
btn.setOnClickListener(clickListener);
btn2.setBackgroundResource(R.drawable.byw);
btn2.setOnClickListener(clickListener_2);
}
OnClickListener clickListener = new OnClickListener() {
public void onClick(View v) {
String name = ((Button) v).getText().toString();
setTitle(name + " button clicked");
}
};
OnClickListener clickListener_2 = new OnClickListener() {
public void onClick(View v) {
finish();
}
};
}
说明:
这个例程,体现了Android中的Listener设计模式:
这里的MyActivity就是ConcreteObserver;而onClick()就是hook method(或称为primitive method)。
View就是Subject。而Button则是ConcreteSubject。