不断地为对象添装饰的设计模式被称为Decorator模式

类图

image.png

Display

  1. public abstract class Display {
  2. public abstract int getColumns();
  3. public abstract int getRows();
  4. public abstract String getRowText(int row);
  5. public final void show() {
  6. for (int i = 0; i < getRows(); i++) {
  7. System.out.println(getRowText(i));
  8. }
  9. }
  10. }

StringDisplay

  1. public class StringDisplay extends Display {
  2. private String string;
  3. public StringDisplay(String str) {
  4. this.string = str;
  5. }
  6. @Override
  7. public int getColumns() {
  8. return string.getBytes().length;
  9. }
  10. @Override
  11. public int getRows() {
  12. return 1;
  13. }
  14. @Override
  15. public String getRowText(int row) {
  16. if (row == 0) {
  17. return string;
  18. } else {
  19. return null;
  20. }
  21. }
  22. }

Border

  1. public abstract class Border extends Display {
  2. protected Display display;
  3. protected Border(Display display) {
  4. this.display = display;
  5. }
  6. }

SideBorder

  1. public class SideBorder extends Border {
  2. private char borderChar;
  3. public SideBorder(Display display, char borderChar) {
  4. super(display);
  5. this.borderChar = borderChar;
  6. }
  7. @Override
  8. public int getColumns() {
  9. return 1 + display.getColumns() + 1;
  10. }
  11. @Override
  12. public int getRows() {
  13. return display.getRows();
  14. }
  15. @Override
  16. public String getRowText(int row) {
  17. return borderChar + display.getRowText(row) + borderChar;
  18. }
  19. }

FullBorder

  1. public class FullBorder extends Border {
  2. public FullBorder(Display display) {
  3. super(display);
  4. }
  5. @Override
  6. public int getColumns() {
  7. return 1 + display.getColumns() + 1;
  8. }
  9. @Override
  10. public int getRows() {
  11. return 1 + display.getRows() + 1;
  12. }
  13. @Override
  14. public String getRowText(int row) {
  15. if (row == 0) {
  16. return "+" + makeLine('-', display.getColumns()) + "+";
  17. } else if (row == display.getRows() + 1) {
  18. return "+" + makeLine('-', display.getColumns()) + "+";
  19. } else {
  20. return "|" + display.getRowText(row - 1) + "|";
  21. }
  22. }
  23. private String makeLine(char ch, int count) {
  24. StringBuffer buf = new StringBuffer();
  25. for (int i = 0; i < count; i++) {
  26. buf.append(ch);
  27. }
  28. return buf.toString();
  29. }
  30. }

类图

image.png

拓展思路的要点

在Decorator模式中,装饰边框与被装饰物具有一致性。即使被装饰物被装饰起来,接口(API)也不会被隐藏起来。其他类依然可以调用getColumns、getRows、getRowText以及show方法。这就是接口的”透明性”。

java.io包

缺点: 导致增加许多很小的类