终于有功夫坐下来把所有Design Pattern好好整理一通了,这可是个盘算了快十年的想法了。
===========================================================================================================
主要参考资料来源:
1. Design Patterns Explained -- Alan Shalloway/James Trott
2. Design Patterns -- The "Gang of Four"
3. 解道 http://www.jdon.com/designpatterns/
4. http://en.wikipedia.org/wiki/Design_Patterns
5. http://www.forestandthetrees.com/designPatterns/
Creational Design Pattern
Singleton,Abstract Factory, Builder, Factory Method, Prototype================================================================================================================
Singleton Design Pattern
对于某个对象,在系统中需要并且只需要一个该对象的实例的情况下使用该模式,常见的象Configuration, Log等。
Prototype Design Pattern
在Java中,clone函数用于实现Prototype模式Factory Method Design Pattern
工厂方法模式:用一个工厂生产同一类型的不同具体对象。如下面这个例子,每当程序需要读一个Image,它都需要创建一个与该Image类型相对应的Reader。创建Reader的逻辑可以使用工厂方法模式。
public class ImageReaderFactory
{
public static ImageReader getImageReader(InputStream is)
{
int imageType = determineImageType(is);
switch(imageType)
{
case ImageReaderFactory.GIF:
return new GifReader(is);
case ImageReaderFactory.JPEG:
return new JpegReader(is);
// etc.
}
}
}
Abstract Factory Design Pattern
这个设计模式用于封装同一类型的不同工厂。下面这个例子是典型的Abstract Factory Pattern. 与上面的工厂模式最大的不同是工厂模式是一个工厂生产不同的具体对象,而Abstract Factory是不同的具体工厂生产不同的对象
interface GUIFactory {
public Button createButton();
}
class WinFactory implements GUIFactory {
public Button createButton() {
return new WinButton();
}
}
class OSXFactory implements GUIFactory {
public Button createButton() {
return new OSXButton();
}
}
interface Button {
public void paint();
}
class WinButton implements Button {
public void paint() {
System.out.println("I'm a WinButton");
}
}
class OSXButton implements Button {
public void paint() {
System.out.println("I'm an OSXButton");
}
}
class Application {
public Application(GUIFactory factory) {
Button button = factory.createButton();
button.paint();
}
}
public class ApplicationRunner {
public static void main(String[] args) {
new Application(createOsSpecificFactory());
}
public static GUIFactory createOsSpecificFactory() {
int sys = readFromConfigFile("OS_TYPE");
if (sys == 0) {
return new WinFactory();
} else {
return new OSXFactory();
}
}
}
Builder Design Pattern
注重抽象对象的构造细节,不同的builder采用不同的构造过程生产产品
public class Pizza { // product
private final String dough;
private final String sauce;
private final String topping;
Pizza(PizzaBuilder builder) {
dough = builder.getDough();
sauce = builder.getSauce();
topping = builder.getTopping();
}
@Override
public String toString() {
return "Dough:" + dough + " Topping:" + topping + " Sauce:" + sauce;
}
}
public class PizzaBuilder {
String dough;
String sauce;
String topping;
public PizzaBuilder withDough(String dough) {
this.dough = dough;
return this;
}
public PizzaBuilder withSauce(String sauce) {
this.sauce = sauce;
return this;
}
public PizzaBuilder withTopping(String topping) {
this.topping = topping;
return this;
}
public String getDough() {
return dough;
}
public String getSauce() {
return sauce;
}
public String getTopping() {
return topping;
}
public Pizza build() {
return new Pizza(this);
}}
public class PizzaBuilderExample {
public static void main(String[] args) {
PizzaBuilder hawaiianPizzaBuilder = new PizzaBuilder().withDough("cross").withTopping("ham+pineapple").withSauce("mild");
Pizza hawaiianPizza = hawaiianPizzaBuilder.build();
System.out.println("Hawaiian Pizza: "+hawaiianPizza);
}
}
Structural Design Pattern
Adaptor, Bridge, Composite, Facade, Proxy-virtual, Decorator,Flyweight
=============================================================================================================
Decorator Design Pattern
动态给一个对象添加一些额外的职责,使用Decorator模式相比用生成子类方式达到功能的扩充显得更为灵活.
为什么使用Decorator?
我们通常可以使用继承来实现功能的拓展,如果这些需要拓展的功能的种类很繁多,那么势必生成很多子类,增加系统的复杂性,同时,使用继承实现功能拓展,我们必须可预见这些拓展功能,这些功能是编译时就确定了,是静态的.
使用Decorator的理由是:这些功能需要由用户动态决定加入的方式和时机.Decorator提供了"即插即用"的方法,在运行期间决定何时增加何种功能. Java API中BufferedReader即是Decorator的一个例子
卖咖啡的例子
// The Coffee Interface defines the functionality of Coffee implemented by decorator
public interface Coffee {
public double getCost(); // returns the cost of the coffee
public String getIngredients(); // returns the ingredients of the coffee
}
// implementation of a simple coffee without any extra ingredients
public class SimpleCoffee implements Coffee {
public double getCost() {
return 1;
}
public String getIngredients() {
return "Coffee";
}
}
下面是各种Decorator
// abstract decorator class - note that it implements Coffee interface
abstract public class CoffeeDecorator implements Coffee {
protected final Coffee decoratedCoffee;
protected String ingredientSeparator = ", ";
public CoffeeDecorator(Coffee decoratedCoffee) {
this.decoratedCoffee = decoratedCoffee;
}
public double getCost() { // implementing methods of the interface
return decoratedCoffee.getCost();
}
public String getIngredients() {
return decoratedCoffee.getIngredients();
}
}
// Decorator Milk that mixes milk with coffee
// note it extends CoffeeDecorator
public class Milk extends CoffeeDecorator {
public Milk(Coffee decoratedCoffee) {
super(decoratedCoffee);
}
public double getCost() { // overriding methods defined in the abstract superclass
return super.getCost() + 0.5;
}
public String getIngredients() {
return super.getIngredients() + ingredientSeparator + "Milk";
}
}
// Decorator Whip that mixes whip with coffee
// note it extends CoffeeDecorator
public class Whip extends CoffeeDecorator {
public Whip(Coffee decoratedCoffee) {
super(decoratedCoffee);
}
public double getCost() {
return super.getCost() + 0.7;
}
public String getIngredients() {
return super.getIngredients() + ingredientSeparator + "Whip";
}
}
<pre name="code" class="java">// Decorator Sprinkles that mixes sprinkles with coffee
// note it extends CoffeeDecorator
public class Sprinkles extends CoffeeDecorator {
public Sprinkles(Coffee decoratedCoffee) {
super(decoratedCoffee);
}
public double getCost() {
return super.getCost() + 0.2;
}
public String getIngredients() {
return super.getIngredients() + ingredientSeparator + "Sprinkles";
}
}
使用: public class Main{
public static void main(String[] args) {
Coffee c = new SimpleCoffee();
System.out.println("Cost: " + c.getCost() + "; Ingredients: " + c.getIngredients());
c = new Milk(c);
System.out.println("Cost: " + c.getCost() + "; Ingredients: " + c.getIngredients());
c = new Sprinkles(c);
System.out.println("Cost: " + c.getCost() + "; Ingredients: " + c.getIngredients());
c = new Whip(c);
System.out.println("Cost: " + c.getCost() + "; Ingredients: " + c.getIngredients()); // Note that you can also stack more than one decorator of the same type
c = new Sprinkles(c);
System.out.println("Cost: " + c.getCost() + "; Ingredients: " + c.getIngredients());
}
}
运行结果
Cost: 1.0; Ingredients: Coffee
Cost: 1.5; Ingredients: Coffee, Milk
Cost: 1.7; Ingredients: Coffee, Milk, Sprinkles
Cost: 2.4; Ingredients: Coffee, Milk, Sprinkles, Whip
Cost: 2.6; Ingredients: Coffee, Milk, Sprinkles, Whip, Sprinkles
Proxy Design Pattern
为其他对象提供一种代理以控制对这个对象的访问。有两种用法:一种是基于性能(内存或速度)考虑,如remote proxy,另外一种是功能增添,比如授权机制控制,为了控制不同的用户对某个对象有不同的访问权限,就可以使用proxy来控制。
interface Image {
void displayImage();
}
// on System A
class RealImage implements Image {
private String filename;
public RealImage(String filename) {
this.filename = filename;
loadImageFromDisk();
}
private void loadImageFromDisk() {
System.out.println("Loading " + filename);
}
public void displayImage() {
System.out.println("Displaying " + filename);
}
}
//on System B
class ProxyImage implements Image {
private String filename;
private RealImage image;
public ProxyImage(String filename) {
this.filename = filename;
}
public void displayImage() {
if (image == null) {
image = new RealImage(filename);
}
image.displayImage();
}
}
class ProxyExample {
public static void main(String[] args) {
Image image1 = new ProxyImage("HiRes_10MB_Photo1");
Image image2 = new ProxyImage("HiRes_10MB_Photo2");
image1.displayImage(); // loading necessary
image1.displayImage(); // loading unnecessary
image2.displayImage(); // loading necessary
image2.displayImage(); // loading unnecessary
image1.displayImage(); // loading unnecessary
}
}
Bridge Design Pattern
用于分离事物的抽象和其具体实现
class Client {
public static void main
(String argv[]) {
Shape r1, r2;
Drawing dp;
dp= new V1Drawing();
r1= new Rectangle(dp,1,1,2,2);
dp= new V2Drawing ();
r2= new Circle(dp,2,2,3);
r1.draw();
r2.draw();
}
}
//对象的抽象
abstract class Shape {
abstract public draw() ;
private Drawing _dp;
Shape (Drawing dp) {
_dp= dp;
}
public void drawLine (
double x1,double y1,
double x2,double y2) {
_dp.drawLine(x1,y1,x2,y2);
}
public void drawCircle (
double x,double y,double r) {
_dp.drawCircle(x,y,r);
}
}
//实现的抽象
abstract class Drawing {
abstract public void drawLine (
double x1, double y1,
double x2, double y2);
abstract public void drawCircle (
double x,double y,double r);
}
class V1Drawing extends Drawing {
public void drawLine (
double x1,double y1,
double x2,double y2) {
DP1.draw_a_line(x1,y1,x2,y2);
}
public void drawCircle (
double x,double y,double r) {
DP1.draw_a_circle(x,y,r);
}
}
class V2Drawing extends Drawing {
public void drawLine (
double x1,double y1,
double x2,double y2) {
// arguments are different in DP2
// and must be rearranged
DP2.drawline(x1,x2,y1,y2);
}
public void drawCircle (
double x, double y,double r) {
DP2.drawcircle(x,y,r);
}
}
class Rectangle extends Shape {
public Rectangle (
Drawing dp,
double x1,double y1,
double x2,double y2) {
super( dp) ;
_x1= x1; _x2= x2 ;
_y1= y1; _y2= y2;
}
public void draw () {
drawLine(_x1,_y1,_x2,_y1);
drawLine(_x2,_y1,_x2,_y2);
drawLine(_x2,_y2,_x1,_y2);
drawLine(_x1,_y2,_x1,_y1);
}
}
class Circle extends Shape {
public Circle (
Drawing dp,
double x,double y,double r) {
super( dp) ;
_x= x; _y= y; _r= r ;
}
public void draw () {
drawCircle(_x,_y,_r);
}
}
// We’ve been given the implementations for DP1 and DP2
class DP1 {
static public void draw_a_line (
double x1,double y1,
double x2,double y2) {
// implementation
}
static public void draw_a_circle(
double x,double y,double r) {
// implementation
}
}
class DP2 {
static public void drawline (
double x1,double x2,
double y1,double y2) {
// implementation
}
static public void drawcircle (
double x,double y,double r) {
// implementation
}
}
Composite Design Pattern
想到Composite就应该想到树形结构图。组合体内这些对象都有共同接口,当组合体一个对象的方法被调用执行时,Composite将遍历整个树形结构,寻找同样包含这个方法的对象并实现调用执行。可以用牵一动百来形容。If programmers find that they are using multiple objects in the same way, and often have nearly identical code to handle each of them, then composite is
a good choice; it is less complex in this situation to treat primitives and composites as homogeneous.
Structure
Component
- is the abstraction for all components, including composite ones
- declares the interface for objects in the composition
- (optional) defines an interface for accessing a component's parent in the recursive structure, and implements it if that's appropriate
Leaf
- represents leaf objects in the composition .
- implements all Component methods
Composite
- represents a composite Component (component having children)
- implements methods to manipulate children
- implements all Component methods, generally by delegating them to its children
import java.util.List;
import java.util.ArrayList;
/** "Component" */
interface Graphic {
//Prints the graphic.
public void print();
}
/** "Composite" */
class CompositeGraphic implements Graphic {
//Collection of child graphics.
private List<Graphic> mChildGraphics = new ArrayList<Graphic>();
//Prints the graphic.
public void print() {
for (Graphic graphic : mChildGraphics) {
graphic.print();
}
}
//Adds the graphic to the composition.
public void add(Graphic graphic) {
mChildGraphics.add(graphic);
}
//Removes the graphic from the composition.
public void remove(Graphic graphic) {
mChildGraphics.remove(graphic);
}
}
/** "Leaf" */
class Ellipse implements Graphic {
//Prints the graphic.
public void print() {
System.out.println("Ellipse");
}
}
/** Client */
public class Program {
public static void main(String[] args) {
//Initialize four ellipses
Ellipse ellipse1 = new Ellipse();
Ellipse ellipse2 = new Ellipse();
Ellipse ellipse3 = new Ellipse();
Ellipse ellipse4 = new Ellipse();
//Initialize three composite graphics
CompositeGraphic graphic = new CompositeGraphic();
CompositeGraphic graphic1 = new CompositeGraphic();
CompositeGraphic graphic2 = new CompositeGraphic();
//Composes the graphics
graphic1.add(ellipse1);
graphic1.add(ellipse2);
graphic1.add(ellipse3);
graphic2.add(ellipse4);
graphic.add(graphic1);
graphic.add(graphic2);
//Prints the complete graphic (four times the string "Ellipse").
graphic.print();
}
}
Behavior Design Pattern
Chain of responsibility, Command, Interpreter, Iterator, Mediator, Memento, Observer, State, Strategy, Template method, Visitor
====================================================================================================
Chain
of Responsibility Pattern
用一系列类(classes)试图处理一个请求request,这些类之间是一个松散的耦合,唯一共同点是在他们之间传递request. 也就是说,来了一个请求,A类先处理,如果没有处理,就传递到B类处理,如果没有处理,就传递到C类处理,就这样象一个链条(chain)一样传递下去--摘自:http://www.jdon.com/designpatterns/cor.htm。Javascript
和 Android框架的事件响应机制是Chain Of responsibility的最为人熟知的例子。
Command Design Pattern
/*the Command interface*/
public interface Command {
void execute();
}
/*the Invoker class*/
import java.util.List;
import java.util.ArrayList;
public class Switch {
private List<Command> history = new ArrayList<Command>();
public Switch() {
}
public void storeAndExecute(Command cmd) {
this.history.add(cmd); // optional
cmd.execute();
}
}
/*the Receiver class*/
public class Light {
public Light() {
}
public void turnOn() {
System.out.println("The light is on");
}
public void turnOff() {
System.out.println("The light is off");
}
}
/*the Command for turning on the light - ConcreteCommand #1*/
public class FlipUpCommand implements Command {
private Light theLight;
public FlipUpCommand(Light light) {
this.theLight = light;
}
public void execute(){
theLight.turnOn();
}
}
/*the Command for turning off the light - ConcreteCommand #2*/
public class FlipDownCommand implements Command {
private Light theLight;
public FlipDownCommand(Light light) {
this.theLight = light;
}
public void execute() {
theLight.turnOff();
}
}
/*The test class or client*/
public class PressSwitch {
public static void main(String[] args){
Light lamp = new Light();
Command switchUp = new FlipUpCommand(lamp);
Command switchDown = new FlipDownCommand(lamp);
Switch s = new Switch();
try {
if (args[0].equalsIgnoreCase("ON")) {
s.storeAndExecute(switchUp);
System.exit(0);
}
if (args[0].equalsIgnoreCase("OFF")) {
s.storeAndExecute(switchDown);
System.exit(0);
}
System.out.println("Argument \"ON\" or \"OFF\" is required.");
} catch (Exception e) {
System.out.println("Argument's required.");
}
}
}
Interpreter Design Pattern
Mediator Design Pattern
各个对象之间的交互操作非常多;每个对象的行为操作都依赖彼此对方,修改一个对象的行为,同时会涉及到修改很多其他对象的行为,如果使用Mediator模式,可以使各个对象间的耦合松散,只需关心和 Mediator的关系,使多对多的关系变成了一对多的关系,可以降低系统的复杂性,提高可修改扩展性.
Mediator - 用于Colleague对象之间互相通信的接口
ConcreteMediator - Mediator的接口实现,协调Colleague对象之间的互相通信
ConcreteColleague - 通过Mediator与其他Colleague交互
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
//Colleague interface
interface Command {
void execute();
}
//Abstract Mediator
interface IMediator {
void book();
void view();
void search();
void registerView(BtnView v);
void registerSearch(BtnSearch s);
void registerBook(BtnBook b);
void registerDisplay(LblDisplay d);
}
//Concrete mediator
class Mediator implements IMediator {
BtnView btnView;
BtnSearch btnSearch;
BtnBook btnBook;
LblDisplay show;
//....
void registerView(BtnView v) {
btnView = v;
}
void registerSearch(BtnSearch s) {
btnSearch = s;
}
void registerBook(BtnBook b) {
btnBook = b;
}
void registerDisplay(LblDisplay d) {
show = d;
}
void book() {
btnBook.setEnabled(false);
btnView.setEnabled(true);
btnSearch.setEnabled(true);
show.setText("booking...");
}
void view() {
btnView.setEnabled(false);
btnSearch.setEnabled(true);
btnBook.setEnabled(true);
show.setText("viewing...");
}
void search() {
btnSearch.setEnabled(false);
btnView.setEnabled(true);
btnBook.setEnabled(true);
show.setText("searching...");
}
}
//A concrete colleague
class BtnView extends JButton implements Command {
IMediator med;
BtnView(ActionListener al, IMediator m) {
super("View");
addActionListener(al);
med = m;
med.registerView(this);
}
public void execute() {
med.view();
}
}
//A concrete colleague
class BtnSearch extends JButton implements Command {
IMediator med;
BtnSearch(ActionListener al, IMediator m) {
super("Search");
addActionListener(al);
med = m;
med.registerSearch(this);
}
public void execute() {
med.search();
}
}
//A concrete colleague
class BtnBook extends JButton implements Command {
IMediator med;
BtnBook(ActionListener al, IMediator m) {
super("Book");
addActionListener(al);
med = m;
med.registerBook(this);
}
public void execute() {
med.book();
}
}
class LblDisplay extends JLabel {
IMediator med;
LblDisplay(IMediator m) {
super("Just start...");
med = m;
med.registerDisplay(this);
setFont(new Font("Arial", Font.BOLD, 24));
}
}
class MediatorDemo extends JFrame implements ActionListener {
IMediator med = new Mediator();
MediatorDemo() {
JPanel p = new JPanel();
p.add(new BtnView(this, med));
p.add(new BtnBook(this, med));
p.add(new BtnSearch(this, med));
getContentPane().add(new LblDisplay(med), "North");
getContentPane().add(p, "South");
setSize(400, 200);
setVisible(true);
}
public void actionPerformed(ActionEvent ae) {
Command comd = (Command) ae.getSource();
comd.execute();
}
public static void main(String[] args) {
new MediatorDemo();
}
}
Memento Design Pattern
memento模式:创建一个新的对象memento用来保存另外一个对象的内部状态拷贝.这样以后就可以将该对象恢复到原先保存的状态.
import java.util.List;
import java.util.ArrayList;
class Originator {
private String state;
// The class could also contain additional data that is not part of the
// state saved in the memento.
public void set(String state) {
System.out.println("Originator: Setting state to " + state);
this.state = state;
}
public Memento saveToMemento() {
System.out.println("Originator: Saving to Memento.");
return new Memento(state);
}
public void restoreFromMemento(Memento memento) {
state = memento.getSavedState();
System.out.println("Originator: State after restoring from Memento: " + state);
}
public static class Memento {
private final String state;
private Memento(String stateToSave) {
state = stateToSave; //注意,在这里,String是一个Immutable的对象,所以可以直接赋值,否则,需要state=stateToSave.clone();来确保state的不变性
}
private String getSavedState() {
return state;
}
}
}
class Caretaker {
public static void main(String[] args) {
List<Originator.Memento> savedStates = new ArrayList<Originator.Memento>();
Originator originator = new Originator();
originator.set("State1");
originator.set("State2");
savedStates.add(originator.saveToMemento());
originator.set("State3");
// We can request multiple mementos, and choose which one to roll back to.
savedStates.add(originator.saveToMemento());
originator.set("State4");
originator.restoreFromMemento(savedStates.get(1));
}
}
Observer Design Pattern
Observer 模式其实就是我们在UI编程时经常使用的Listener机制。它定义了一种一对多的依赖关系,当一个对象的状态发生变化,其所有依赖方都获得通知并自动响应。
/* File Name : EventSource.java */
package obs;
import java.util.Observable; //Observable is here
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class EventSource extends Observable implements Runnable {
public void run() {
try {
final InputStreamReader isr = new InputStreamReader( System.in );
final BufferedReader br = new BufferedReader( isr );
while( true ) {
String response = br.readLine();
setChanged();
notifyObservers( response );
}
}
catch (IOException e) {
e.printStackTrace();
}
}
}
/* File Name: ResponseHandler.java */
package obs;
import java.util.Observable;
import java.util.Observer; /* this is Event Handler */
public class ResponseHandler implements Observer {
private String resp;
public void update (Observable obj, Object arg) {
if (arg instanceof String) {
resp = (String) arg;
System.out.println("\nReceived Response: "+ resp );
}
}
}
/* Filename : MyApp.java */
/* This is the main program */
package obs;
public class MyApp {
public static void main(String args[]) {
System.out.println("Enter Text >");
// create an event source - reads from stdin
final EventSource evSrc = new EventSource();
// create an observer
final ResponseHandler respHandler = new ResponseHandler();
// subscribe the observer to the event source
evSrc.addObserver( respHandler );
// starts the event thread
Thread thread = new Thread(evSrc);
thread.start();
}
}
State Design Pattern
interface State {
void writeName(StateContext stateContext, String name);
}
class StateA implements State {
public void writeName(StateContext stateContext, String name) {
System.out.println(name.toLowerCase());
stateContext.setState(new StateB());
}
}
class StateB implements State {
private int count=0;
public void writeName(StateContext stateContext, String name){
System.out.println(name.toUpperCase());
// change state after StateB's writeName() gets invoked twice
if(++count>1) {
stateContext.setState(new StateA());
}
}
}
<pre name="code" class="java">//<span style="font-family:sans-serif;font-size:13px;color:#000000;font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 19px; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); display: inline !important; float: none; ">The context class has a state variable which it instantiates in an initial state, in this case StateA.
</span>public class StateContext {
private State myState;
public StateContext() {
setState(new StateA());
}
// normally only called by classes implementing the State interface
public void setState(State newState) {
this.myState = newState;
}
public void writeName(String name) {
this.myState.writeName(this, name);
}
}
//And the usage:
public class TestClientState {
public static void main(String[] args) {
StateContext sc = new StateContext();
sc.writeName("Monday");
sc.writeName("Tuesday");
sc.writeName("Wednesday");
sc.writeName("Thursday");
sc.writeName("Saturday");
sc.writeName("Sunday");
}
}
Output: monday TUESDAY WEDNESDAY thursday SATURDAY SUNDAY
Strategy Design Pattern
Strategy 模式的意图是使用聚合封装(encapsulate)替代继承来表示一个类的行为,它根据事物发生时的上下文场景使用不同的业务规则或算法来解决问题。strategy模式将算法的分离
// The classes that implement a concrete strategy should implement this.
// The context class uses this to call the concrete strategy.
interface Strategy {
int execute(int a, int b);
}
// Implements the algorithm using the strategy interface
class ConcreteStrategyAdd implements Strategy {
public int execute(int a, int b) {
System.out.println("Called ConcreteStrategyAdd's execute()");
return a + b; // Do an addition with a and b
}
}
class ConcreteStrategySubtract implements Strategy {
public int execute(int a, int b) {
System.out.println("Called ConcreteStrategySubtract's execute()");
return a - b; // Do a subtraction with a and b
}
}
class ConcreteStrategyMultiply implements Strategy {
public int execute(int a, int b) {
System.out.println("Called ConcreteStrategyMultiply's execute()");
return a * b; // Do a multiplication with a and b
}
}
// Configured with a ConcreteStrategy object and maintains a reference to a Strategy object
class Context {
private Strategy strategy;
// Constructor
public Context(Strategy strategy) {
this.strategy = strategy;
}
public int executeStrategy(int a, int b) {
return strategy.execute(a, b);
}
}
// Test application
class StrategyExample {
public static void main(String[] args) {
Context context;
// Three contexts following different strategies
context = new Context(new ConcreteStrategyAdd());
int resultA = context.executeStrategy(3,4);
context = new Context(new ConcreteStrategySubtract());
int resultB = context.executeStrategy(3,4);
context = new Context(new ConcreteStrategyMultiply());
int resultC = context.executeStrategy(3,4);
}
}
Template Method Design Pattern
Template Method 模式其实就是Java中的抽象类和实现其抽象方法的派生类机制。
Visitor Design Pattern
作用于某个对象群中各个对象的操作. 它可以使你在不改变这些对象本身的情况下,定义作用于这些对象的新操作.例子:
interface CarElementVisitor {
void visit(Wheel wheel);
void visit(Engine engine);
void visit(Body body);
void visit(Car car);
}
interface CarElement {
void accept(CarElementVisitor visitor); // CarElements have to provide accept().
}
class Wheel implements CarElement {
private String name;
public Wheel(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void accept(CarElementVisitor visitor) {
visitor.visit(this);
}
}
class Engine implements CarElement {
public void accept(CarElementVisitor visitor) {
visitor.visit(this);
}
}
class Body implements CarElement {
public void accept(CarElementVisitor visitor) {
visitor.visit(this);
}
}
class Car implements CarElement {
CarElement[] elements;
public CarElement[] getElements() {
return elements.clone(); // Return a copy of the array of references.
}
public Car() {
this.elements = new CarElement[]//create new Array of elements
{ new Wheel("front left"), new Wheel("front right"),
new Wheel("back left") , new Wheel("back right"),
new Body(), new Engine() };
}
public void accept(CarElementVisitor visitor) {
for(CarElement element : this.getElements()) {
element.accept(visitor);
}
visitor.visit(this);
}
}
class CarElementPrintVisitor implements CarElementVisitor {
public void visit(Wheel wheel) {
System.out.println("Visiting " + wheel.getName()
+ " wheel");
}
public void visit(Engine engine) {
System.out.println("Visiting engine");
}
public void visit(Body body) {
System.out.println("Visiting body");
}
public void visit(Car car) {
System.out.println("Visiting car");
}
}
class CarElementDoVisitor implements CarElementVisitor {
public void visit(Wheel wheel) {
System.out.println("Kicking my " + wheel.getName() + " wheel");
}
public void visit(Engine engine) {
System.out.println("Starting my engine");
}
public void visit(Body body) {
System.out.println("Moving my body");
}
public void visit(Car car) {
System.out.println("Starting my car");
}
}
public class VisitorDemo {
static public void main(String[] args) {
Car car = new Car();
car.accept(new CarElementPrintVisitor());
car.accept(new CarElementDoVisitor());
}
}