您的位置:首页 > 编程语言 > Java开发

java设计模式学习笔记第四章

2016-03-07 17:35 751 查看
外观模式(Facade)

外观模式的意图是为子系统提供一个接口,便于它们的使用。

示例类则用于展示如何使用类或子系统。

挑战4.1写出示例类和外观类的亮点区别。

个人认为示例类就是为使用此类做了一个示例,供参考。外观类是提供接口,有工具类的特点。

正确答案:

  1.示例通常是一个单独运行的应用程序,而外观不是。

  2.示例通常包含了样本数据,而外观则没有。

  3.外观通常是可配置的,示例不是。

  4.外观用在产品代码中,示例不是。

正确答案感觉很官方啊,我是没有完全的深入体会。只能继续往下看深入学习。

重构到外观模式

下面模拟了放哑弹的抛物线。



showFlight类混杂了三个功能。一,为飞行路径提供面板。二,作为一个完整的应用程序,需要将飞行路径的面板显示在一个具有标题的边框内,三,计算飞行路径的抛物线。

showFlight类可以工作,然而根据关注点分离的原则,我们应该将其重构为多个单独的类,以提高可维护性及可重用性。做了以下改变:

  1.引入一个Function类,它定义了f()方法,接收一个double值(时间值),返回一个double值(函数的值)。

  2.将ShowFlight类移入PlotPanel类,改为使用Function对象来获取x和y的值。定义PlotPanel构造函数接收两个Function实例和绘图所需的点数。

  3.将createTitlePanel()方法移到已存在的UI工具类中,来实现一个像当前ShowFlight类那样带有标题的面板。

挑战4.4完成图,用以展示将ShowFlight重构为三个类的代码:Function类,实现两个参数功能的PloatPanel和一个UI外观类。在你的重新设计中,让类ShowFlight2为获取y值创建一个Function,并让main()方法启动程序。

我写的版块



正确答案:



本书的代码将UI方法声明为非静态的,这样UI的子类就可以重写他们,从而能够为用户界面的构建提供不同的工具实现。为了让标准的用户界面是可用的,设计参考了单例的NORMAL对象。

重构之后,Function类定义了参数方程。倘若要创建一个包含Function类与其他类型的com.oozinoz.function包,则Function.java的核心代码可能是:

public abstract double f(double t);

经过重构,PlotPanel类只拥有了一个职责:显示一对参数方程,代码如下:

public class PlotPanel extends JPanel{
private int points;
private int[] xpoints;
private int[] ypoints;

private Function xFunction;
private Function yFunction;
public PlotPanel(int nPoint,Function xFunc,Function yFunc){
points = nPoint;
xpoints = new int[points];
ypoints = new int[points];
xFunction = xFunc;
yFunction = yFunc;
setBackground(Color.WHITE);
}
protected void paintComponent(Graphics graphics){
double w = getWidth() - 1;
double h = getHeight() - 1;
for(int i = 0; i < points; i ++){
double t = ((double)i)/(points - 1);
xPoints[i] = (int)(xFunction.f(t)*w);
yPoints[i] = (int)(h*(1 - yFunction.f(t)));
}
graphics.drawPolyline(xPoints,yPoints,points);
}
}


注意,PlotPanel类目前是com.oozinoz.ui包的一部分,和UI类处于同一位置。对ShowFlight类进行重构后,UI类也拥有了createTitledPanel和createTitledBorder方法,UI类逐步演化为外观类。使之更容易使用java控件。

使用这些控件的应用程序可能是一个很小的类,该类唯一的职责就是对这些控件进行布局并显示它们。

public class ShowFlight2{
public static void main(String[] args){
PlotPanel p = new PlotPanel(
101,
new T(),
new ShowFlight().new YFunction());
p.setPreferredSize(new Dimension(300,200));

JFrame frame = new JFram("Flight path for shell Duds");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(
UI.NORMAL.createTitledPanel("Flight path",p));
frame.pack();
frame.setVisible(true);
}
private class YFunction extends Function{
public YFunction(){
super(new Function[]{});
}
public double f(double t){
//当t等于0或1时,y为0;当t等于0.5时,y为1
return 4*t*(1-t);
}
}
}


public class UI{
public static final UI NORMAL = new UI();
protected Font font = new Font("Book Antiqua",Font.PLAIN,18);
//省略部分实现
public Font getFont(){
return font;
}
public TitledBorder createTitledBorder(String title){
TitleBorder border = BorderFactory.createTitledBorder(
BorderFactory.createBevelBorder(BevelBorder.RAISED),
title,
TitleBorder.LEFT,
TitleBorder.TOP);
border.setTitleColor(Color.black);
border.setTitleFone(getFont());
return border;
}
public JPanel createTitledPanel(String title,JPanel in){
JPanel out = new JPanel();
out.add(in);
out.setBorder(createTitledBorder(title));
return out;
}
}


对代码理解:

PlotPanel类接收Function类,来计算抛物线的点。然后画出来。然后把PlotPanel以参数的形式扔进UI类的createTitlePanel方法。改方法就会创建出来代标题的样板了。ShowFlight2好像是一个示例(demo),创建一个JFrame容器来装UI创建出来的带标题的面板。然后JFrame展现出来。功能都由PlotPanel,Function,UI类实现。并且Function是最底层的实现,PlotPanel是Function的上一层。封装了它,创建出了JPanel类。然后UI用创建出来的JPanel类。来实现最外层的功能。UI是最接近用户的。也就是程序员看得到的,可以调用的,它很简单。UI.NORMAL.createTitledPanel("Flight path",p)一句话就把代标题的面板创建出来了。然后测试的demo类用JFrame展示它。

总结

整体而言应该对子系统中的类进行重构,知道每个类都有一个明确的目的。这可以使你的代码更容易维护,但也可能让使用该子系统的用户变得无所适从。为了让调用这些代码的开发人员更方便,可以为子系统提供示例程序或者外观类。通常,示例程序可以独立运行,却无法重用,仅用于演示使用子系统的方法。外观类则是可配置、可重用的类,提供了高层次的接口,是的子系统的使用更加方便。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: