zoukankan      html  css  js  c++  java
  • 《重构,改善现有代码的设计》第八章 Duplicate Observed Data

    Java代码 复制代码 收藏代码
    1. import java.awt.Color;
    2. import java.awt.Container;
    3. import java.awt.FlowLayout;
    4. import java.awt.Label;
    5. import java.awt.TextField;
    6. import java.awt.event.FocusAdapter;
    7. import java.awt.event.FocusEvent;
    8. import java.awt.event.WindowAdapter;
    9. import java.awt.event.WindowEvent;
    10. import java.util.Observable;
    11. import java.util.Observer;
    12. import javax.swing.JFrame;
    13. /**
    14. * 《重构,改善现有代码的设计》第八章 Duplicate Observed Data
    15. *
    16. * 业务逻辑:
    17. * 一个JFrame(类IntervalWindow)有三个TextField,分别是start,end和length
    18. * 如果你修改Start或End,length就会自动成为两者计算所得的长度
    19. * 如果你修改length,End就会随之改变(start不变)
    20. *
    21. * 主要是使用了Observer模式:
    22. * start,end和length之间的运算,是与具体界面无关的,应该独立出来(成为一个Subject,观察者模式里面的“目标”)
    23. *
    24. * 关键在于解决以下两个问题:
    25. * 1.什么时候计算?当界面上的TextField值有变动时,由WindowObserver调用Subject的set方法
    26. * 2.计算后如何通知界面?Subject调用notifyObservers方法,这个方法会触发WindowObserver的update方法
    27. *
    28. */
    29. public class ObserveGUIWindow {
    30. public static void main(String[] args) {
    31. new WindowObserver().init();
    32. }
    33. }
    34. class WindowObserver implements Observer {
    35. private TextField startField;
    36. private TextField endField;
    37. private TextField lengthField;
    38. private Subject subject;
    39. public void init() {
    40. JFrame f = new JFrame("This is a test");
    41. f.setSize(200, 200);
    42. Container content = f.getContentPane();
    43. content.setBackground(Color.white);
    44. content.setLayout(new FlowLayout());
    45. startField = new TextField("0", 10);
    46. endField = new TextField("0", 10);
    47. lengthField = new TextField("0", 10);
    48. SymFocus listener = new SymFocus();
    49. startField.addFocusListener(listener);
    50. endField.addFocusListener(listener);
    51. lengthField.addFocusListener(listener);
    52. Label startLabel = new Label("start:");
    53. Label endLabel = new Label("end:");
    54. Label lengthLabel = new Label("length:");
    55. content.add(startLabel);
    56. content.add(startField);
    57. content.add(endLabel);
    58. content.add(endField);
    59. content.add(lengthLabel);
    60. content.add(lengthField);
    61. f.setLocationRelativeTo(null);
    62. f.setVisible(true);
    63. f.addWindowListener(new WindowAdapter() {
    64. public void windowClosing(WindowEvent e) {
    65. System.exit(0);
    66. }
    67. });
    68. subject = new Subject();
    69. subject.addObserver(this);
    70. }
    71. //更新界面,最新的值(计算后)来自Subject
    72. public void update(Observable o, Object arg) {
    73. Subject subject = (Subject)o;
    74. startField.setText(subject.getStart());
    75. endField.setText(subject.getEnd());
    76. lengthField.setText(subject.getLength());
    77. }
    78. class SymFocus extends FocusAdapter {
    79. public void focusLost(FocusEvent event) {
    80. Object object = event.getSource();
    81. if (object == startField)
    82. StartFieldFocusLost(event);
    83. else if (object == endField)
    84. EndFieldFocusLost(event);
    85. else if (object == lengthField)
    86. LengthFieldFocusLost(event);
    87. }
    88. }
    89. void StartFieldFocusLost(FocusEvent event) {
    90. //从界面取得输入的值
    91. String start = startField.getText();
    92. subject.setStart(isInteger(start) ? start : "0");
    93. //交由Subject计算
    94. subject.calculateLength();
    95. }
    96. void EndFieldFocusLost(FocusEvent event) {
    97. String end = endField.getText();
    98. subject.setEnd(isInteger(end) ? end : "0");
    99. subject.calculateLength();
    100. }
    101. void LengthFieldFocusLost(FocusEvent event) {
    102. String length = lengthField.getText();
    103. subject.setLength(isInteger(length) ? length : "0");
    104. subject.calculateEnd();
    105. }
    106. boolean isInteger(String str) {
    107. return str != null && str.matches("[0-9]+");
    108. }
    109. }   
  • 相关阅读:
    哪种写法更好?<script></script> vs/or <script type=”text/javasript”></script>
    JS 脚本应该放在页面哪个位置 head body foot
    List<T> ForEach break
    嵌套JSON 取出name与value
    C# 改变图片尺寸(压缩),Image Resize
    tornado
    appachebench网站压力测试
    mysql分区分表
    redis的持久化存储,RDB与AOF
    MEMCACHE的内存管理和删除策略
  • 原文地址:https://www.cnblogs.com/bjanzhuo/p/3575895.html
Copyright © 2011-2022 走看看