装饰(Decorator)模式又名包装(Wrapper)模式[GOF95]。装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个代替方案。
//抽象构件(Component)
public interface Component
{
void sampleOperation();
}
//具体构件(Concrete Component)
public class ConcreteComponent implements Component
{
public void sampleOperation()
{
// Write your code here
}
}
//装饰(Decorator)
public class Decorator implements Component
{
public Decorator(Component component)
{
// super();
this.component = component;
}
public Decorator() {
}
public void sampleOperation()
{
component.sampleOperation();
}
private Component component;
}
//具体装饰(Concrete Decorator)
public class ConcreteDecorator extends Decorator
{
public void sampleOperation()
{
super.sampleOperation();
}
}
一个用Java语言实现的Grep系统
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.FilterReader;
public class GrepReader extends FilterReader
{
protected String substring; // substring to be matched
protected BufferedReader in; // InputReader
public GrepReader( FileReader in, String substring )
{
super( in );
this.in = new BufferedReader( in );
this.substring = substring;
lineNumber = 0;
}
public final String readLine( ) throws IOException
{
String line;
// step forward until line matching substring
do
{
line = in.readLine( ); lineNumber++;
} while ( (line != null) && line.indexOf( substring ) == -1 );
return line;
}
private int lineNumber;
public int lineNo( ) { return lineNumber; }
} // class GrepReader
import java.io.PrintStream;
public class GrepView
{
PrintStream out ;
public GrepView()
{
out = System.out;
}
public void println(String line)
{
out.println(line);
}
}
import java.io.*;
/** This class implements a subset of the UNIX tool grep and
** demonstrates the use of the GrepInputStream class.
** It prints the filename, linenumbers and lines of the file that
** contains a specified substring (no regexp)
** @see GrepInputStream
** @author Ulrik Schroeder
** @version Joop97-Demo
**/
public class Grep {
static GrepReader g; // own FilterReader definition
private static GrepView gv = new GrepView();
/** reads substring and files to be looked through from commandline.
** Unfortunately DOS shell does not expand wildcards when calling Grep.
** @param args command line arguments: 1 substring, 2 .. n Filenames
** @see <{DataInputStream}>
** @see GrepInputStream
** @see GrepInputStream#GrepInputStream
** @see GrepInputStream#line
** @see GrepInputStream#lineNo
**/
public static void main( String[] args )
{
if ( args.length <= 1 )
{
gv.println("Usage: java Grep
gv.println("
gv.println("
System.exit( 1 );
}
String line;
try
{
gv.println( "\nGrep: 搜索 " + args[0] + " 文件 " + args[1] );
gv.println( "文件行号\t\t 下面的行里含有所搜索的字符串\n" );
// gv.println( "\n--> Grep: searching " + args[ 0 ] + " in " + args[ i ] + " <----------" );
// gv.println( "File:Line:\t Line containing substring\n" );
g = new GrepReader( new FileReader( args[1] ), args[0] );
for( ; ; )
{
line = g.readLine( );
if (line == null) break;
gv.println( args[1] + g.lineNo( ) + ":\t" + line );
} // loop through lines of file
g.close( );
} // try
catch ( IOException e ) {
gv.println( e.getMessage() );
} // catch IOException
}
}
一个例子:发票系统
package com.javapatterns.decorator.printinvoice;
import java.util.Date;
import java.util.Vector;
import java.text.NumberFormat;
abstract public class Order
{
/**
* @link aggregation
* @directed
* @supplierCardinality 0..*
* @clientCardinality 1
*/
private OrderLine lnkOrderLine;
protected String customerName;
protected Date salesDate;
protected Vector items = new Vector(10);
public void print()
{
for (int i = 0 ; i < items.size() ; i++)
{
OrderLine item = (OrderLine) items.get(i);
item.printLine();
}
}
public String getCustomerName()
{
return customerName;
}
public void setCustomerName(String customerName)
{
this.customerName = customerName;
}
public Date getSalesDate()
{
return salesDate;
}
public void setSalesDate(Date salesDate)
{
this.salesDate = salesDate;
}
public void addItem(OrderLine item)
{
items.add(item);
}
public void remoteItem(OrderLine item)
{
items.remove(item);
}
public double getGrandTotal()
{
double amnt = 0.0D;
for (int i = 0 ; i < items.size() ; i++)
{
OrderLine item = (OrderLine) items.get(i);
amnt += item.getSubtotal();
}
return amnt;
}
protected String formatCurrency(double amnt)
{
return NumberFormat.getCurrencyInstance().format(amnt);
}
}
package com.javapatterns.decorator.printinvoice;
public class SalesOrder extends Order
{
public SalesOrder() {
}
public void print()
{
super.print();
}
}
package com.javapatterns.decorator.printinvoice;
abstract public class OrderDecorator extends Order
{
/**
* @link aggregation
* @directed
* @supplierCardinality 1
* @clientCardinality 0..1
*/
protected Order order;
public OrderDecorator(Order order)
{
this.order = order;
this.setSalesDate( order.getSalesDate() );
this.setCustomerName( order.getCustomerName() );
}
public void print()
{
super.print();
}
}
package com.javapatterns.decorator.printinvoice;
public class HeaderDecorator extends OrderDecorator
{
public HeaderDecorator(Order anOrder)
{
super(anOrder);
}
public void print()
{
this.printHeader();
super.order.print();
}
private void printHeader()
{
System.out.println("\t***\tI N V O I C E\t***\nXYZ Incorporated\nDate of Sale: "
+ order.getSalesDate());
System.out.println("========================================================");
System.out.println("Item\t\tUnits\tUnit Price\tSubtotal");
}
}
package com.javapatterns.decorator.printinvoice;
import java.text.NumberFormat;
public class FooterDecorator extends OrderDecorator
{
public FooterDecorator(Order anOrder)
{
super(anOrder);
}
public void print()
{
super.order.print();
printFooter();
}
private void printFooter()
{
System.out.println("========================================================");
System.out.println("Total\t\t\t\t" +
formatCurrency(super.order.getGrandTotal()));
}
}
package com.javapatterns.decorator.printinvoice;
import java.text.NumberFormat;
public class OrderLine
{
private String itemName;
private int units;
private double unitPrice;
public String getItemName()
{
return itemName;
}
public void setItemName(String itemName)
{
this.itemName = itemName;
}
public int getUnits()
{
return units;
}
public void setUnits(int units)
{
this.units = units;
}
public double getUnitPrice()
{
return unitPrice;
}
public void setUnitPrice(double unitPrice)
{
this.unitPrice = unitPrice;
}
public void printLine()
{
System.out.println(itemName + "\t" + units
+ "\t" + formatCurrency(unitPrice)
+ "\t" + formatCurrency(getSubtotal()));
}
public double getSubtotal()
{
return unitPrice * units;
}
private String formatCurrency(double amnt)
{
return NumberFormat.getCurrencyInstance().format(amnt);
}
}
package com.javapatterns.decorator.printinvoice;
import java.util.Date;
public class Client {
/**
* @directed
*/
private static Order order;
public static void main(String[] args)
{
rder = new SalesOrder();
order.setSalesDate(new Date());
order.setCustomerName("XYZ Repair Shop");
OrderLine line1 = new OrderLine();
line1.setItemName("FireWheel Tire");
line1.setUnitPrice(154.23);
line1.setUnits(4);
order.addItem(line1);
OrderLine line2 = new OrderLine();
line2.setItemName("Front Fender");
line2.setUnitPrice(300.45);
line2.setUnits(1);
order.addItem(line2);
rder = new HeaderDecorator(new FooterDecorator(order));
order.print();
}
}
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/12993749/viewspace-225975/ ,如需转载,请注明出处,否则将追究法律责任。