组合模式
- 在文件系统中,文件夹和文件具有一致性
- 将文件夹和文件当作同一种东西看
示例
模拟一个文件系统。文件和文件夹都具有名称和大小,我们将其抽象成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的实现,只对其做一些修饰