前言:IoC(Inversion of Control)就是「反向控制」之意思。反向调用就意味着反向控制,也就是说,框架基类控制了AP 子类,这是符合框架设计原则的,也符合Hollywood(好莱坞)大明星的原则。

wKioL1MFd2yjSC3SAAEfgKFAUB8610.jpg

ee                                                                        ee

欢迎访问 ==>高老师的博客网页

高焕堂:MISOO(大数据.大思考)联盟.台北中心和东京(日本)分社.总教练


EE                                                                        EE

平台框架开发的<好莱坞大明星原则>


1. 把握好莱坞大明星原则:

Don’t call me, I’ll call you back!

   顾名思义,IoC(Inversion of Control)就是「反向控制」之意思。IoC观念和机制源自于OOP语言(如C++、Java等)的类继承(Inheritance)机制,例如Java语言中,基类(Super-class)的函数可以主动呼叫子类(Subclass)之函数,这就是一般所谓的IoC机制。后来,人们常将这些基类聚集起来,就称之为框架(Framework)。反向控制又称为「控制反转」或「反向调用」。而反向调用的相反词就是:正向调用。正向调用就是AP子类调用基类的函数。例如,下图里的FirstActivity调用Activity基类的setContentView()函数。

01215508-42af5471d58d4eaebde772b4904a290

图1  Android的正向调用之例

反向调用恰好相反,表示由基类调用子类的函数。例如,下图里的Activity调用FirstActivity应用子类的onCreate()函数。

01215545-d7016040f7574d129b88f79ac80bfa5

图2  Android的反向调用之例

   正向调用就意味着正向控制,也就是说,AP 子类控制了框架基类,这是违背框架设计原则的。这项设计原则就如同Hollywood(好莱坞)大明星的名言:“Don’t call me, I’ll call you back.”,如下图:

01215613-349b96eb629943dd8900d2b29884537

图3  正向调用:AP掌握控制权

 上图所示的正向控制,既违背了好莱坞大明星的原则,也违背框架设计的原则。那么,该如何修正呢? 改为反向控制就行了。如下图:

01215641-95124900121040628324aec5216f447

图4  反向调用:框架掌握控制权

     反向调用就意味着反向控制,也就是说,框架基类控制了AP 子类,这是符合框架设计原则的,也符合Hollywood(好莱坞)大明星的原则。请看看Java代码如何实现这项原则:

//  FirstActivity.java

package com.misoo.pkmm;

import java.util.ArrayList;

import android.app.Activity;

import android.content.Intent;

import android.os.Bundle;

import android.view.View;

import android.widget.AdapterView;

import android.widget.ListView;

import android.widget.AdapterView.OnItemClickListener;

public class FirstActivity extends Activity implements OnItemClickListener {

          ArrayList<Row> coll;

          @Override

   public void onCreate(Bundle icicle)  // I (框架) call You

{

       super.onCreate(icicle);

       coll = new ArrayList<Row>();

       coll.add(new Row("MP3", R.drawable.mp3_icon));

       coll.add(new Row("MP4",R.drawable.mp4_icon) );

       coll.add(new Row("Exit", R.drawable.icon2));

       ListView lv = new ListView(this);

       lv.setAdapter(new myAdapter(this, coll));

       lv.setOnItemClickListener(this);

       setContentView(lv);// You(AP) call me

  }

           @Override

           protected void onActivityResult(int requestCode, int resultCode, Intent data) {

// I (框架) call You

                      Intent intent = new Intent(FirstActivity.this, VideoActivity.class);

                      startActivity(intent);

// You(AP) call me

              }

           public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {

// I (框架) call You

                    if(arg2 == 0) {

                               Intent intent = new Intent(FirstActivity.this, mp3Activity.class);

                               startActivity(intent); // You(AP) call me


                    }

                    else if(arg2 == 1){

                               Intent intent = new Intent(FirstActivity.this, LoadActivity.class);

                               intent.putExtra("resid", R.raw.nice);

                               startActivityForResult(intent, 0); // You(AP) call me

                    }

                    else if(arg2 == 2)

                               finish();  // You(AP) call me

          }

}

无论是.NET或Android母框架的设计,都依循着这项基本原则,让框架掌握控制权,也让掌握框架者能成为强龙。[歡迎光臨 高煥堂 網頁: http://www.cnblogs.com/myEIT/ ]


2.  掌握框架设计的时间(Time)元素

 软件是人们知识(Knowledge)的一种呈现(Representation)。面向对象(Object-Oriented)计算机语言里的继承(Inheritance)机制,让人们可以将类(Class)区分为基类(Base class or Super class)和子类(Subclass)。于是,可将人们的知识分开为两种,然后分别表现于基类与子类里,如下图:

01215707-f8013282f057474380892374e116331

图5  两种知识的分与合

 分开表现之后,藉由计算机语言的编译器将基类与子类结合起来,成为完整的类(即含有完整的知识)。这些完整的类就是完整的软件,也是可以在计算机里执行的软件,让计算器具有人们的智慧,呈现出人们所期待的行为。那么,如何将人们知识分为两种呢?如何切分呢?答案是:以用户(User)出现的时间点(Time-point)为基准点而切分开来。于是,就分出两种知识了,包括:

  • 领域知识--- 在用户出现之前,软件发展者(Developer)所能获得的知识。就是领域的共通性知识,简称:领域知识(Domain Knowledge)。

  • 应用知识--- 在用户出现之后,软件发展者所能获得的知识。就是应用的特殊性知识,简称:应用知识(Application Knowledge)或用户知识(User Knowledge)。

兹以时间为主轴,绘出图形如下:

01220130-5c41070a9d79495189b7ed109efa7d6

图6  知识获得的时间轴

   从上图可看出来,开发者是先获得领域知识;经过数天、数个月或数年之后,用户出现了,才会获得应用知识。领域知识先表达于基类,而应用知识则后表达于子类。然后使用程序编译器将它们结合起来,成为完整可用的软件了,如下图:

01220304-0adf713e4e9e4686bf389d824f2052b

图7  透过代码编译来汇合两种知识

从上图可看出来,将这些基类集合起来,就成为该特殊领域框架(Domain-Specific Framework, 简称DSF)了。


3. 需求的时间轴

开启JUDE建模工具,并点选<File/New>,建立了新的模型,建立新的类图(Class Diagram),画面上呈现出绘图区。接着,可以拉出一个类的图像,并取名为「汽车」:

01220319-5170bf58fb27436d8e960e7ef7f6f71

这个完整的汽车,就相当于一颗完整的大理石。假设我们先不做轮胎(因为轮胎是由客户选择的,而目前客户尚未出现),于是就学习老子的智慧:

「无之以为用」(例如,将畚箕挖空才会有用)

也依循伟大雕刻师罗丹( Musée Rodin)所说:

「雕刻之道:把不必要的部分去掉」

01220346-ea216ecc0eb84c9399e038483627433

图 8  罗丹的雕刻之道:把「不」必要的部分去掉


由于要等客户出现才能决定轮胎,所以客户到来之前,先不做轮胎。于是,框架设计的时间轴为:

01220405-7323ca3259164cd494704d085bb1ba1

图9  汽车需求知识获得的时间轴


于是,把轮胎部分去掉,先不做轮胎,而得出「汽车×××」(或「轮毂」),如下图所示:

01220427-2b0a78129c314fc1969f6cb8bef62cb

图10 挖掉轮胎之后,先做部分就是框架了

=========================================================

相關文章:<Android与iOS/WP8跨平台整合设计与开发 专栏>

~ End~