1.基于事件的隐式调用风格
基本组件:对象或过程,并分类为以下更小的组件
–过程或函数,充当事件源或事件处理器的角色
–事件
连接件:事件-过程绑定
–过程(事件处理器,事件的接收和处理方) 向特定的
事件进行注册;
–组件(事件源) 发布事件;
–当某些事件被发布(触发) 时,向其注册的过程被隐式调用;
–调用的次序是不确定的;
优点
§支持实现交互式系统(用户输入/网络通讯)
§异步执行,不必同步等待执行结果
§对事件的并发处理将提高系统性能;
缺点:
分布式控制方式使系统的同步、验证和调试变得异常困难:
–组件放弃了对系统计算的控制,难以控制各模块之间的处理次序。一个组件触发一个事件时,不能确定其它组件是否会响应它。而且即使它知道事件注册了哪些组件的构成,它也不能保证这些过程被调用的顺序。
–既然过程的语义必须依赖于被触发事件的上下文约束,关于正确性的推理则难以保证。
–传统的基于先验和后验条件的验证变得不可能。
程序一:
package com.button;
import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.Label;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
class BtnLabelAction extends Frame implements ActionListener
{
//声明窗口类(BtnLabelAction)并实现动作事件接口(ActionListener)
Label prompt;
Button btn;
void CreateWindow()
{
setTitle("MyButton");
prompt = new Label("你好"); //创建标签对象
btn = new Button("操作"); //创建按钮对象
setLayout(new FlowLayout()); //布局设计,用于安排按钮、标签的位置
add(prompt); //将标签放入容器
add(btn); //将按钮放入容器
btn.addActionListener(this); //将监听器(窗体对象本身)注册给按钮对象
setSize(300,100);
setVisible(true);
}
public void actionPerformed(ActionEvent e) //接口ActionListener的事件处理方法
{
if(e.getSource()==btn) //判断动作事件是否是由按钮btn引发的
if(prompt.getText()=="你好")
prompt.setText("再见");
else
prompt.setText("你好");
}
}
public class BtnTest
{
public static void main(String[] args)
{
// TODO Auto-generated method stub
BtnLabelAction bla=new BtnLabelAction();
bla.CreateWindow();
}
}
程序二:
package com.button;
import java.awt.Button;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.Label;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JTextField;
class ButtonLabelTest extends Frame implements ActionListener{
Label label;
JTextField textField;
Button button;
void CreateView(){
setSize(300, 200);
setTitle("基于事件的隐式调用风格");
setBackground(Color.orange);
label=new Label("你的姓名:");
textField=new JTextField();
textField.setText("杨旭");
button=new Button("得到你的姓名");
setLayout(new FlowLayout());
add(label);
add(textField);
add(button);
button.addActionListener(this);
setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if(e.getSource()==button){
if(textField.getText()=="杨旭"){
textField.setText("海哥");
}
else{
textField.setText("杨旭");
}
}
}
}
public class ButtonTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
ButtonLabelTest test=new ButtonLabelTest();
test.CreateView();
}
}
2.管道-过滤器软件体系结构风格
组件:过滤器,处理数据流
&&一个过滤器封装了一个处理步骤
–-数据源点和数据终止点可以看作是特殊的过滤器过滤器对输入流进行处理、转换,处理后的结果在输出端流出。
§&每个组件都有输入/输出集合,组件在输入处读取数据流,经过内部处理,在输出处生成数据流。
连接件:管道,连接一个源和一个目的过滤器
–-转发数据流
–-数据可能是ASCII字符形成的流连接件位于过滤器之间,起到信息流的导管的作用,被称为管道。接件就象是数据流传输的管道,将一个过滤器的输出传到另一过滤器的输入。
—管道过滤器优点:由于每个组件的行为不受其他组件的影响,整个系统的行为易于理解
§&系统中的组件具有良好的隐蔽性和高内聚、低耦合的特点;
–—支持软件复用:
•允许设计者将整个系统的输入/输出行为看成是多个过滤器的行为的简单合成;
•只要提供适合在两个过滤器之间传送的数据,任何两个过滤器都可被连接起来;
—系统维护和增强系统性能简单:
•新的过滤器可以添加到现有系统中来,旧的可以被改进的过滤器替换掉;允许对一些如吞吐量、死锁等属性的分析;
§支持并行执行:
–每个过滤器是作为一个单独的任务完成,因此可与其它任务并行执行。
&*管道-过滤器风格的缺点:
§&通常导致进程成为批处理的结构
–这是因为虽然过滤器可增量式地处理数据,但它们是独立的,所以设计者必须将每个过滤器看成一个完整的从输入到输出的转换;
§&不适合处理交互的应用
—当需要增量地显示改变时,这个问题尤为严重;处理两个独立但又相关的数据流是可能会遇到困难
§&在数据传输上没有通用的标准,每个过滤器都增加了解析和合成数据的工作,这样就导致了系统性能下降,并增加了编写过滤器的复杂性。
–—绝大部分处理时间消耗在格式转换上(需要对数据传输进行特定的处理时,会导致对于每个过滤器的解析输入和格式化输出要做更多的工作,带来系统复杂性的上升)
程序:
package com.person;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
class Sender extends Thread
{
PipedOutputStream out=new PipedOutputStream();
public PipedOutputStream getOut()
{
return out;
}
@Override
public void run()
{
// TODO Auto-generated method stub
String str="海哥,你好!\n";
try
{
out.write(str.getBytes());
out.close();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class Receiver extends Thread
{
PipedInputStream in=new PipedInputStream();
public PipedInputStream getIn()
{
return in;
}
@Override
public void run()
{
// TODO Auto-generated method stub
byte [] buf = new byte[1024];
try
{
int len=in.read(buf);
System.out.println("下面是Sender函数接受到的数据:\n"+new String(buf, 0,len));
in.close();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class TestPigedPerson
{
public static void main(String[] args)
{
// TODO Auto-generated method stub
Sender S=new Sender();
Receiver R=new Receiver();
PipedInputStream In=R.getIn();
PipedOutputStream Out=S.getOut();
try
{
In.connect(Out);//两个输入输出相连
R.start();
S.start();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
截图: