设计模式学习(5)一致性

组合模式

  • 在文件系统中,文件夹和文件具有一致性
  • 将文件夹和文件当作同一种东西看

示例

模拟一个文件系统。文件和文件夹都具有名称和大小,我们将其抽象成Entry。

但是文件夹可以add文件或者文件夹,文件却不能add

class FileTreatmentException extends RuntimeException {
    public FileTreatmentException() {

    }

    public FileTreatmentException(String msg) {
        super(msg);
    }
}

public abstract class Entry {
    public abstract String getName();
    public abstract int getSize();
    public Entry add(Entry entry) throws FileTreatmentException {
        throw new FileTreatmentException();
    }
    protected abstract void printList(String prefix);
    public String toString() {
        return getName() + " (" + getSize() + ") ";
    }
}

public class Directory extends Entry{
    private String name;
    private ArrayList directory = new ArrayList();
    public Directory(String name) {
        this.name = name;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public int getSize() {
        Iterator it = directory.iterator();
        int size = 0;
        while (it.hasNext()) {
            Entry entry = (Entry)it.next();
            size += entry.getSize();
        }
        return size;
    }

    public Entry add(Entry entry) {
        directory.add(entry);
        return this;
    }

    @Override
    protected void printList(String prefix) {
        System.out.println(prefix + "/" + this);
        Iterator it = directory.iterator();
        while (it.hasNext()) {
            Entry entry = (Entry) it.next();
            entry.printList(prefix + "/" + name);
        }
    }
}

public class File extends Entry{
    public String name;
    private int size;

    public File(String name, int size) {
        this.name = name;
        this.size = size;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public int getSize() {
        return size;
    }

    @Override
    protected void printList(String prefix) {
        System.out.println(prefix + "/" + this);
    }
}

装饰器模式

  • 不断给类添加装饰的模式

示例

public abstract class Display {
    public abstract int getColumns();
    public abstract int getRows();
    public abstract String getRowText(int row);
    public final void show() {
        for (int i = 0; i < getRows(); i++) {
            System.out.println(getRowText(i));
        }
    }
}

public class StringDisplay extends Display {
    private String string;

    public StringDisplay(String string) {
        this.string = string;
    }

    @Override
    public int getColumns() {
        return string.getBytes().length;
    }

    @Override
    public int getRows() {
        return 1;
    }

    @Override
    public String getRowText(int row) {
        if (row == 0) return string;
        else return null;
    }
}

public abstract class Border extends Display {
    protected Display display;
    protected Border(Display display) {
        this.display = display;
    }
}

public class SideBorder extends Border {
    private char borderChar;
    protected SideBorder(Display display,char ch) {
        super(display);
        this.borderChar = ch;
    }

    @Override
    public int getColumns() {
        return 1 + display.getColumns() + 1;
    }

    @Override
    public int getRows() {
        return display.getRows();
    }

    @Override
    public String getRowText(int row) {
        return borderChar + display.getRowText(row) + borderChar;
    }
}

public class FullBorder extends Border{

    public FullBorder(Display display) {
        super(display);
    }
    @Override
    public int getColumns() {
        return 1 + display.getColumns() + 1;
    }

    @Override
    public int getRows() {
        return 1 + display.getRows() + 1;
    }

    @Override
    public String getRowText(int row) {
        if (row == 0) return "+" + makeLine('-', display.getColumns()) + "+";
        else if (row == display.getRows() + 1) return "+" + makeLine('-', display.getColumns()) + "+";
        else return "|" + display.getRowText(row - 1) + "|";
    }

    private String makeLine(char ch, int count) {
        StringBuffer buf = new StringBuffer();
        for (int i = 0; i < count; i++) {
            buf.append(ch);
        }
        return buf.toString();
    }
}


public class DecoratorTest {
    public static void main(String[] args) {
        Display b1 = new StringDisplay("hello world");
        Display b2 = new SideBorder(b1, '#');
        Display b3 = new FullBorder(b2);

        b1.show();
        b2.show();
        b3.show();
    }
}
  • 这里的装饰器继承了Display,同时还拥有一个display成员
  • 继承display是为了在装饰以后,能调用Display的方法,保持接口相同
  • 拥有一个display是为了保持原有display的实现,只对其做一些修饰
posted @ 2022-08-20 17:05  Destiny233  阅读(23)  评论(0)    收藏  举报