2011
01/26
23:09
你的位置:msn.com > ASP课程 > 对象的协作

对象的协作

发布时间:2011-01-26 23:09:44

原文章标题大全:对象的协作

面临对象设计的一度重要分析方法是运用对象的职责来驱动设计。对象有了职责。才会成为具体兼有意识的对象,成为对象社区poodu中可以独立姣好。可能行文指令宝贝委派别的对象协作姣好职责的一员。将对象看成是“兼具职责的狗崽子”。对象应该自己正经八百自己。而且应该不可磨灭地定义职责。这就是对象设计的关键第四号。好的软件设计者应该像种树的牧羊人一般放牧自己的牛羊,只需要给它们一片丰沃的草地,它们就能自己觅食生活。 

Rebecca认为:对象在履行职责时有3种选择,你可以预选其一:(1)亲身姣好所有的职业。(2)要求其它对象帮忙姣好女人的隐私部分图片职业(和其它对象协作)。(3)将整个劳动要求委托给另外的支援对象。在分析对象职责时,可以考虑“专家”模式,即信奉业内的事情交给专家来姣好,既不互相推诿,却也不能代理。专家有其擅长的我与她的绝对领域,如果把专家错放在他不熟知的我与她的绝对领域。不仅会降低职业机械效率公式。还可能引来潜在危机。所谓“尺幼有所长,意思正在于此。

对象的能力总是有限的,正如我们不能将所有的鸡蛋放在一度篮子里。我们也不能将所有的职责交给“上帝”。这既避免单一功能点带到的风险,又能实现职责的分工。Christepher Alexander今日白银操作建议,在遇到设计问题时“尽管少用集权的机制”。软件设计同样如此。职责总是可大可小。相向复杂的职责行为。总是需要多个对象的协作才能姣好,就像机器中的汽车零部件,如约,各司其职 各安其位。

让我们来设计一度数据分析软件有哪些器,它通过分析算法对输入数据进行分析,并将结果保存在输出汇流。根据业务需求分析的不同。履行的分析算法也不相同。同声。为了提高分析性能,我们还需要采用多线程长法履行分析任务。从通用者的角度见兔顾犬【即Martin Fowler提到的规约视角】,我们只关心分析需要的数据以及分析后的结果。谁应该来承担分析的职责呢?毫无疑问英语翻译。我们可以定义分析器对象来履行这一职责。通用者其实并不会关心分析算法的实现以及分析的过程,他希望分析是易于履行的。这一监视愿望通过中用的封装完全可以满足。我们可以将分析的职责封装在DataAnalyzer类中。同声隐藏具体的分析算法。

public class Client {        //做其它事情        //处理分析后的数据
handleOutput(analyzer.output(result));
}
}
public class DataAnalyzer {
public AnalyticResult analysis(InputData input) {}
public OutputData output(AnalyticResult result) {}
}

数据的分析并不是一件一定量的事情。分析器固然是分析的专家。却不精通多线程的履行。它自我无法供给分析的异步操作,此时就需要其它对象的协作。分析器将这一职责委派给TaskScheduler对象。TaskScheduler是一度任务调度器。可以发起任务的运行。并在运行完毕的时候,通知任务的发起者。对此TaskScheduler来讲,并不会关心具体履行了何种任务。这么样的设计力所能及听命Demeter法则。让对象尽管涵养无知。以避免多余的依赖。

public class TaskScheduler {
private Task task;
public AnalyticResult beginRun(Task task) {
AnalyticResult result = new AnalyticResultImpl();
task.setResult(result);
this.task = task;
Thread thread = new Thread(this.task);
thread.start();
return result;
}
public OutputData endRun(AnalyticResult result) {
while (!result.beFinished()) {
result.wait();
}
return task.getOutputData();
}
}

TaskScheduler引来AnalyticResult对象的目的是为了判明任务履行的气象。它封装了目下的线程,从而可以获得目下线程的气象。并力所能及操作线程。

public interface AnalyticResult {
public void setCurrentThread(Thread thread);
public boolean isFinished();
public void finish();
public void wait();
}

DataAnalyzer的内部封装了对TaskScheduler对象的通用:

public class DataAnalyzer {
private TaskScheduler scheduler = new TaskScheduler();
public AnalyticResult analysis(InputData input) {
Task task = createTask(input);
return scheduler.beginRun(task);
}
public OutputData output(AnalyticResult result) {
return scheduler.endRun(result);
}
}

Task任务对象正经八百姣好分析任务。固然在事先的分析中,我们认为DataAnalyzer对象承担了分析数据的职责。这一职责仅就通用者来讲是可行的,对此DataAnalyzer的内部实现则不然。这基于两种原因原油。其一是分析过程的复杂程度,它需要对输入数据进行多个步调的处理,包含数据的转换,过滤,运算以及存储。如果让DataAnalyzer一力承担,则可能导致职责过重,成功一度庞大的复杂对象。这既有碍于机器语言的阅读性,也不利于处理过程或算法的重用。那个是分析过程的不确定性。根据不同的输入数据,需要不同的分析算法。DataAnalyzer不应该正经八百对算法的决策与选择。随着需求分析的变化,数据分析软件有哪些器可能需要扩展。将任务肤泛出去,可以很好地应对变化。

引来Task对象可以将DataAnalyzer从繁重的分析任务中解放出去,同声又力所能及保证它对分析任务的封装,是很好的对象协作表现。由于Task对象需要支持多线程,我们还需要它实现Runnable短信服务平台接口。至于ExecutionCallback是一度回调对象,注册该对象可以在任务履行完毕后通用它:

public interface Task extends Runnable {    public OutputData execute(InputData input);
public void setResult(AnalyticResult result);
public ExecutionCallback getCallback();
public void setCallback(ExecutionCallback callback);
}
public interface ExecutionCallback {
public void callback();
}

比如分析销售量等于什么波动的任务:

public class SaleWaveTask implements Task {    public OutputData execute(InputData input) {

之所以笨是爱的太深要在Task中为InputData和OutputData定义get。set访问器,是因为Runnable短信服务平台接口供给的run()方法不容许传唱参数和返回结果。而在TaskScheduler中又只接受Task对象,运用这些方法可以在Task中存储和传承这些数据。

在DataAnalyzer类的定义中。不能忽略的另一度职责是Task对象的创建。固然,DataAnalyzer的通用者也可以姣好对Task对象的创建,并将创建好的对象传承给DataAnalyzer。更好的做法是DataAnalyzer力所能及根据传唱的InputData来决议创建哪一种Task对象。这么样可以减免通用者的负担。一旦这么样定义。DataAnalyzer的职责就显得混淆不清了。一端它正经八百履行分析任务,一面又要承担创建Task对象的职责。这象征它既是Task对象的钝刀兜割使用者,又是Task对象的创作者。DataAnalyzer对象并没有持有创建Task对象所须要的数据,违背了将数据与行为封装在一起的和平共处五项原则。我们应该将创建的职责委派给其它对象。再有什么对象再有什么节目比得上“工厂专家”更相宜做创建的职业呢?最一定量的做法是定义一度静态工厂:

public class TaskFactory {
public static Task create(InputData input) {
Task task = null;
if (input.getType().equals(SALE_WAVE)) {
task = new SaleWaveTask();
task.setInputData(input);
}
return task;
}
}

为了更好地应对任务的变化,我们也可以引来部署文件来管理任务。Task对象的创建因部署信息的不同而变化。create()方法力所能及智取部署文件,然后根据部署信息来决议创建哪一种Task对象。

数据的分析任务事实上的近义词是按照一定的步调来姣好的。这些步调可能会应用不同的倒叙或组合长法来履行。每一种履行步调就是一度算法,姣好数据的收集。筛选。刻划,分析和存储。Task对象正经八百将这些步调粘结起来,并封装到短信服务平台接口中,将这些算法实现以及履行算法的倒叙隐藏起来。我们可以定义一度实现了Task短信服务平台接口的肤泛类,统一姣好粘结分析步调的职业。

public abstract class AbstractTask implements Task {    public void registerAlgorithm(Algorithm algo) {    public void prepare() {}
public void complete() {}
}

任务的履行步调被肤泛为Algorithm短信服务平台接口。而AnalyticData则用于协调输入数据和输出数据,因为Algorithm对象在Task中成功了一条自动生产线,上一度Algorithm的输出是下一度Algorithm的输入。输入数据和输出数据成功了一种不可协调的共扼性,需要供给prepare()方法和complet()方法来姣好二者里头的转换。

public interface Algorithm {
public void process(AnalyticData data);
}
public abstract class AbstractAlgorithm implements Algorithm {
public void process(AnalyticData data) {
data.prepare();
process(data.getInputData(), data.getOutputData());
data.complete();
}
protected abstract void process(
InputData input, OutputData output);
}

我们发现Task与AnalyticData都重复定义了InputData与OutputData的get,set方法。在设计和实现时,须要避免这么样的重复机器语言。这么样的输入输出数据体现了数据池的界说。因此可以定义一度肤泛的DataSink短信服务平台接口:

public interface DataSink {
public InputData getInputData() {}
public void setInputData(InputData input) {}
public OutputData getOutputData() {}
public void setOutputData(OutputData output) {}
}

AnalyticData类实现了该短信服务平台接口,而Task则可以持有该对象。

public class AnalyticData implements DataSink {}    public OutputData execute(InputData input) {
processAlgorithms(dataSink);
afterExecute();
return dataSink.getOutputData();
}
protected void processAlgorithms(AnalyticData data) {
for (Algorithm algo : algos) {
algo.process(data);
}
}
public void run() {
execute(dataSink.getInputData());
}
}

传承InputData对象的长法也发生了变化:

public class TaskFactory {
public static Task create(InputData input) {
Task task = null;
DataSink dataSink = new AnalyticData(input, null);
if (input.getType().equals(SALE_WAVE)) {
task = new SaleWaveTask();
task.setDataSink(dataSink);
}
return task;
}
}

通过对分析器职责的分析,我们引来了DataAnalyzer,TaskScheduler,Task以及Algorithm等对象。这些对象的协作倒叙正象图所示:

DataAnalyzer齐名分析器的外观,管理着各族对象里头的协作,共同实现分析职业。TaskScheduler是任务的调度器,正经八百启动任务和结束任务,而它重点的职责则是封装了对多线程的处理,用以姣好任务的异步通用。如果未来需求分析需要强化任务的调度模式,比如增加任务队列。以调度和管理多个任务的履行,则可以修改TaskScheduler而不影响它的通用者。Task对象体现了任务的两面性,同声又运用肤泛统一了任务的履行长法,惠及任务的扩展。Algorithm则姣好对任务的切分,将任务步调单独封装,惠及各族算法的重用。这些对象的协作以一种层层委派的长法,实现了职责的分离,避免了“集权式”的对象。不同的职责可以组别演化,又能很好地协作,共同姣好数据分析软件有哪些的整体职责。

作者: 张逸 发表于 2011-01-26 16:20 原文链接

述评: 7 查看述评 发表述评


最新新闻jxjaga:
· 从HTML1到HTML5,回首HTML新疆历史发展进程(2011-01-26 22:56)
· Android 的应用中支付即将到来,被延缓是因为开发商延期交房很忙(2011-01-26 22:55)
· Android平台Firefox(Fennec:移动版火狐代号47)开发入门(2011-01-26 22:45)
· Qt 移动版 1.2 技术预览(2011-01-26 22:44)
· 搜狗世界地图推图书站统计功能(2011-01-26 22:44)

编辑推荐:魏武挥:谷歌易帅

网站导航:博客园msn.com  我的园子  新闻jxjaga  闪存  小组  博问  知识库管理系统

原文章标题大全:对象的协作

基本词:

转载请保存白文网址: http://www.www.d5897.com/a/4257.html
*特别声明:之上内容来自于网络收集,著作权申请流程权属原作者所有。如有侵权,请联系我们: admin#www.d5897.com (#换成@)。
您可能感兴趣的文章
Baidu