设计模式快速参考

简要描述了软件设计中常用的一些设计模式,并给出了简单的示例代码。

设计模式快速参考

构造模式

http://www.java2s.com/Tutorials/Java/Java_Design_Patterns/index.htm 主要描述如何更好地表述一个对象。主要有如下一些具体模式:

抽象工厂(Abstract Factory)

抽象工厂也称为工厂的工厂,它创建其他的工厂。使用抽象工厂时,先创建 一个超级工厂,通过这个超级工厂,创建其他的工厂类,利用这些工厂类创 建对象。

情景示例

假设创建一些形状和打印机两类对象,对于形状类型,我们有圆,长方形和正 方形,对于打印机类型,我们有纸质打印机,网络打印机以及屏幕打印机。 对于形状类型,接口定义如下:

interface Shape {
    void draw();
}

接下来创建一些具体的形状类:

class Rectangle implements Shape {

    @Override
    public void draw() {
        System.out.println("Inside Rectangle::draw() method.");
    }
}
class Square implements Shape {

    @Override
    public void draw() {
        System.out.println("Inside Square::draw() method.");
    }
}
class Circle implements Shape {

    @Override
    public void draw() {
        System.out.println("Inside Circle::draw() method.");
    }
}

然后创建打印机接口

interface Printer{
   void print();
}

接着创建一些具体的打印机类

class PaperPrinter implements Printer {
    @Override
    public void print() {
        System.out.println("Papter");
    }
}

class WebPrinter implements Printer {
    @Override
    public void print() {
        System.out.println("Web");
    }
}

class ScreenPrinter implements Printer {
    @Override
    public void print() {
        System.out.println("Screen");
    }
}

最后创建一个抽象类来获取创建形状和打印机对象的工厂类

abstract class AbstractFactory {
   abstract Printer getPrinter(String type);
   abstract Shape getShape(String shape) ;
}

最后,我们创建一些具体的工厂类来创建对应的对象

class ShapeFactory extends AbstractFactory {

    @Override
    public Shape getShape(String shapeType){
        if(shapeType == null){
            return null;
        }    
        if(shapeType.equalsIgnoreCase("CIRCLE")){
            return new Circle();
        } else if(shapeType.equalsIgnoreCase("RECTANGLE")){
            return new Rectangle();
        } else if(shapeType.equalsIgnoreCase("SQUARE")){
            return new Square();
        }
        return null;
    }

    @Override
    Printer getPrinter(String type) {
        return null;
    }
}
class PrinterFactory extends AbstractFactory {

    @Override
    public Shape getShape(String shapeType){
        return null;
    }

    @Override
    Printer getPrinter(String type) {
        if(type == null){
            return null;
        }    
        if(type.equalsIgnoreCase("paper")){
            return new PaperPrinter();
        } else if(type.equalsIgnoreCase("web")){
            return new WebPrinter();
        } else if(type.equalsIgnoreCase("Screen")){
            return new ScreenPrinter();
        }
        return null;
    }
}

最后,创建一个工厂的产生类,通过不同的参数返回不同的工厂类:

class FactoryProducer {
    public static AbstractFactory getFactory(String choice){
        if(choice.equalsIgnoreCase("SHAPE")){
            return new ShapeFactory();
        } else if(choice.equalsIgnoreCase("Printer")){
            return new PrinterFactory();
        }
        return null;
    }
}

下面代码显示的如何使用抽象工厂类来创建不同的对象:

public class Main {
    public static void main(String[] args) {

        //get shape factory
        AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE");

        //get an object of Shape Circle
        Shape shape1 = shapeFactory.getShape("CIRCLE");

        //call draw method of Shape Circle
        shape1.draw();

        //get an object of Shape Rectangle
        Shape shape2 = shapeFactory.getShape("RECTANGLE");

        //call draw method of Shape Rectangle
        shape2.draw();

        //get an object of Shape Square 
        Shape shape3 = shapeFactory.getShape("SQUARE");

        //call draw method of Shape Square
        shape3.draw();

        //get printer factory
        AbstractFactory printerFactory = FactoryProducer.getFactory("printer");

        Printer printer1 = printerFactory.getPrinter("Paper");
        printer1.print();
        Printer printer2 = printerFactory.getPrinter("Web");
        printer2.print();
        Printer printer3 = printerFactory.getPrinter("Screen");
        printer3.print();
    }
}

总体的类结果如下:

2016081330.png

构造器(Builder)

构造器模式是使用一些简单的对象去创建一个更复杂的对象。它一步步地 从小而简单的对象中创建更大的对象。

情景分析

例如,当我们创建一个应用程序的主窗体时,我们需要创建一个菜单, 一个工具栏,然后将它们加入到主窗体中。

对于每个窗体,我们需要创建一个空的窗体,创建一个菜单,工具栏, 并将菜单、工具栏安装到窗体中。

class Menu {
}
class ToolBar {
}
class MainWindow {
    Menu menu;
    ToolBar toolBar;
    public Menu getMenu() {
        return menu;
    }
    public void setMenu(Menu menu) {
        this.menu = menu;
    }
    public ToolBar getToolBar() {
        return toolBar;
    }
    public void setToolBar(ToolBar toolBar) {
        this.toolBar = toolBar;
    }
}
class WindowBuilder{
    public static MainWindow createWindow(){
        MainWindow window = new MainWindow();
        Menu menu = new Menu();
        ToolBar toolBar = new ToolBar();
        window.setMenu(menu);
        window.setToolBar(toolBar);
        return window;
    }
}
public class Main {
    public static void main(String[] args) {
        MainWindow object = WindowBuilder.createWindow();

    }
}

类关系图如下:

@startuml
package "Component Objects" {
        class Menu
        class ToolBar
}

class MainWindow {
      Menu menu
     ToolBar toolBar

     +Menu getMenu()
     +void setMenu(Menu menu)
     +ToolBar getToolBar()
     +void setToolBar(ToolBar toolBar)
}

MainWindow o-- Menu
MainWindow o-- ToolBar

class WindowBuilder {
      static MainWindow createWindow()
}

WindowBuilder -- MainWindow

class Main

Main --> WindowBuilder: <<use>>

@enduml

2016082901.png

工厂方法(Factory Method)

defines an abstract class that creates objects but lets each subclass decide which object to create.

定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一 个类的实例化延迟到其子类。

工厂方法将使用者隐藏了对象创建的逻辑。

情景分析

定义Shape接口:

public interface Shape {
   void draw();
}

定义Rectangle类:

public class Rectangle implements Shape {
   @Override
   public void draw() {
      System.out.println("Inside Rectangle::draw() method.");
   }
}

定义Square类:

public class Square implements Shape {

   @Override
   public void draw() {
      System.out.println("Inside Square::draw() method.");
   }
}

定义Circle类:

public class Circle implements Shape {

   @Override
   public void draw() {
      System.out.println("Inside Circle::draw() method.");
   }
}

定义ShapeFactory类:

public class ShapeFactory {

   //use getShape method to get object of type shape 
   public Shape getShape(String shapeType){
      if(shapeType == null){
         return null;
      }    
      if(shapeType.equalsIgnoreCase("CIRCLE")){
         return new Circle();
      } else if(shapeType.equalsIgnoreCase("RECTANGLE")){
         return new Rectangle();
      } else if(shapeType.equalsIgnoreCase("SQUARE")){
         return new Square();
      }
      return null;
   }
}

下面是使用工厂类的示例:

public class Main {

   public static void main(String[] args) {
      ShapeFactory shapeFactory = new ShapeFactory();

      //get an object of Circle and call its draw method.
      Shape shape1 = shapeFactory.getShape("CIRCLE");

      //call draw method of Circle
      shape1.draw();

      //get an object of Rectangle and call its draw method.
      Shape shape2 = shapeFactory.getShape("RECTANGLE");

      //call draw method of Rectangle
      shape2.draw();

      //get an object of Square and call its draw method.
      Shape shape3 = shapeFactory.getShape("SQUARE");

      //call draw method of circle
      shape3.draw();
   }
}

类图

2016051801.png

原型(Prototype)

原型模式拥有较好的性能去复制对象。

在原型模式中,一般返回对象的拷贝而不是重新创建一个新的对象。

如果创建一个新的对象代价很多,特别是涉及到递归时,会考虑使用原型 模式。

情景分析

创建抽象类:

abstract class Shape implements Cloneable {

   private String id;
   protected String type;

   abstract void draw();

   public String getType(){
      return type;
   }

   public String getId() {
      return id;
   }

   public void setId(String id) {
      this.id = id;
   }

   public Object clone() {
      Object clone = null;
      try {
         clone = super.clone();
      } catch (CloneNotSupportedException e) {
         e.printStackTrace();
      }
      return clone;
   }
}

创建三个具体子类:

class Rectangle extends Shape {

   public Rectangle(){
     type = "Rectangle";
   }

   @Override
   public void draw() {
      System.out.println("Inside Rectangle::draw() method.");
   }
}
class Square extends Shape {

   public Square(){
     type = "Square";
   }

   @Override
   public void draw() {
      System.out.println("Inside Square::draw() method.");
   }
}
class Circle extends Shape {

   public Circle(){
     type = "Circle";
   }

   @Override
   public void draw() {
      System.out.println("Inside Circle::draw() method.");
   }
}

创建ShapeProtoType ,它返回不同shape子类的原型:

class ShapeProtoType{
  /*w w w .  j a va  2  s. co  m*/
   private static Hashtable<String, Shape> shapeMap 
      = new Hashtable<String, Shape>();

   public static Shape getShape(String shapeId) {
      Shape cachedShape = shapeMap.get(shapeId);
      return (Shape) cachedShape.clone();
   }
   public static void loadCache() {
      Circle circle = new Circle();
      circle.setId("1");
      shapeMap.put(circle.getId(),circle);

      Square square = new Square();
      square.setId("2");
      shapeMap.put(square.getId(),square);

      Rectangle rectangle = new Rectangle();
      rectangle.setId("3");
      shapeMap.put(rectangle.getId(),rectangle);
   }
}
public class Main{
   public static void main(String[] args) {
      ShapeProtoType.loadCache();

      Shape clonedShape = (Shape) ShapeProtoType.getShape("1");
      System.out.println("Shape : " + clonedShape.getType());    

      Shape clonedShape2 = (Shape) ShapeProtoType.getShape("2");
      System.out.println("Shape : " + clonedShape2.getType());    

      Shape clonedShape3 = (Shape) ShapeProtoType.getShape("3");
      System.out.println("Shape : " + clonedShape3.getType());    
   }
}

类关系图:

2016082902.png

单例(Singleton)

单例 模式涉及一个类,主要是为了保持这个类的对象任何时候只能有一 个实例存在。

情景分析

class MainWindow {
   //create an object of MainWindow
   private static MainWindow instance = new MainWindow();

   //make the constructor private so that this class cannot be
   //instantiated by other class
   private MainWindow(){}

   //Get the only object available
   public static MainWindow getInstance(){
      return instance;
   }

   public void showMessage(){
      System.out.println("Hello World!");
   }
}

public class Main {
   public static void main(String[] args) {
      //Get the only object available
      MainWindow object = MainWindow.getInstance();

      //show the message
      object.showMessage();
   }
}

示例图:

2016082903.png

结构模式

主要描述组织对象和类以完成更大的目标。主要有如下一些具体模式:

适配器(Adapter)

适配器是两个不兼容的实体之间的转换器,适配器模式是一种结构型模式, 它做为两个不兼容的接口之间的桥梁。通过适配器,我们可以将两个不兼容 的接口统一起来。

情景分析

创建一个播放任何媒体文件的Player接口, MyPlayer是适配器,它统一了 播放媒体文件的各种接口。

interface Player {
    public void play(String type, String fileName);
}/*from  w  w  w .j a v  a2s .  c o m*/
interface AudioPlayer {  
    public void playAudio(String fileName);
}
interface VideoPlayer {  
    public void playVideo(String fileName);
}
class MyAudioPlayer implements AudioPlayer {
    @Override
    public void playAudio(String fileName) {
        System.out.println("Playing. Name: "+ fileName);    
    }
}
class MyVideoPlayer implements VideoPlayer {
    @Override
    public void playVideo(String fileName) {
        System.out.println("Playing. Name: "+ fileName);    
    }
}

class MyPlayer implements Player {

    AudioPlayer audioPlayer = new MyAudioPlayer();
    VideoPlayer videoPlayer = new MyVideoPlayer();

    public MyPlayer(){      
    }
    @Override
    public void play(String audioType, String fileName) {
        if(audioType.equalsIgnoreCase("avi")){
            videoPlayer.playVideo(fileName);
        }else if(audioType.equalsIgnoreCase("mp3")){
            audioPlayer.playAudio(fileName);
        }
    }
}
public class Main{
    public static void main(String[] args) {
        MyPlayer myPlayer = new MyPlayer();

        myPlayer.play("mp3", "h.mp3");
        myPlayer.play("avi", "me.avi");
    }
}

示例图:

2016091001.png

桥接(Bridge)

桥接模式将定义与其实现分开,在该模式中,有一个接口充当桥接的角色, 桥接使得具体类与接口实现类之间相互独立。

情景分析

interface Printer {
   public void print(int radius, int x, int y);
}/*www  .ja v  a  2s  . com*/
class ColorPrinter implements Printer {
   @Override
   public void print(int radius, int x, int y) {
      System.out.println("Color: " + radius +", x: " +x+", "+ y +"]");
   }
}
class BlackPrinter implements Printer {
   @Override
   public void print(int radius, int x, int y) {
      System.out.println("Black: " + radius +", x: " +x+", "+ y +"]");
   }
}
abstract class Shape {
   protected Printer print;
   protected Shape(Printer p){
      this.print = p;
   }
   public abstract void draw();  
}
class Circle extends Shape {
   private int x, y, radius;

   public Circle(int x, int y, int radius, Printer draw) {
      super(draw);
      this.x = x;  
      this.y = y;  
      this.radius = radius;
   }

   public void draw() {
      print.print(radius,x,y);
   }
}
public class Main {
   public static void main(String[] args) {
      Shape redCircle = new Circle(100,100, 10, new ColorPrinter());
      Shape blackCircle = new Circle(100,100, 10, new BlackPrinter());

      redCircle.draw();
      blackCircle.draw();
   }
}

示例图:

2016091002.png

组合(Composite)

组合模式会创建一种树型结构来代表一组对象,并对一组对象视为单个对象, 使用一个类来代表一个树型结构。

情景分析

import java.util.ArrayList;
import java.util.List;
//from w w w .j  av  a  2 s  .  com
class Employee {
   private String name;
   private String title;
   private List<Employee> subordinates;

   public Employee(String name,String title) {
      this.name = name;
      this.title = title;
      subordinates = new ArrayList<Employee>();
   }

   public void add(Employee e) {
      subordinates.add(e);
   }

   public void remove(Employee e) {
      subordinates.remove(e);
   }

   public List<Employee> getSubordinates(){
     return subordinates;
   }

   public String toString(){
      return "Employee :[ Name : "+ name 
      +", dept : "+ title +subordinates +" ]";
   }   
}

public class Main {
   public static void main(String[] args) {
      Employee CEO = new Employee("John","CEO");

      Employee headSales = new Employee("Rob","Sales");

      Employee headMarketing = new Employee("Mike","Marketing");

      Employee programmer1 = new Employee("Lili","Programmer");
      Employee programmer2 = new Employee("Bob","Programmer");

      Employee tester1 = new Employee("Jack","Tester");
      Employee tester2 = new Employee("Tom","Tester");

      CEO.add(headSales);
      CEO.add(headMarketing);

      headSales.add(tester1);
      headSales.add(tester2);

      headMarketing.add(programmer1);
      headMarketing.add(programmer2);

      //print all employees of the organization
      System.out.println(CEO); 
      for (Employee headEmployee : CEO.getSubordinates()) {
         System.out.println(headEmployee);
         for (Employee employee : headEmployee.getSubordinates()) {
            System.out.println(employee);
         }
      }    
   }
}

修饰器(Decorator)

修饰器模式在不改变原有类型的基础上增加新的功能,它充当一种包装器, 对现有的类进行功能扩展。

情景分析

interface Printer {
   void print();//from w  w  w  .j  a  v a2 s .  co  m
}
class PaperPrinter implements Printer {
   @Override
   public void print() {
      System.out.println("Paper Printer");
   }
}
class PlasticPrinter implements Printer {
   @Override
   public void print() {
      System.out.println("Plastic Printer");
   }
}
abstract class PrinterDecorator implements Printer {
   protected Printer decoratedPrinter;
   public PrinterDecorator(Printer d){
      this.decoratedPrinter = d;
   }
   public void print(){
      decoratedPrinter.print();
   }  
}
class Printer3D extends PrinterDecorator {
   public Printer3D(Printer decoratedShape) {
      super(decoratedShape);    
   }
   @Override
   public void print() {
     System.out.println("3D.");
     decoratedPrinter.print();         
   }
}
public class Main {
   public static void main(String[] args) {
      Printer plasticPrinter = new PlasticPrinter();
      Printer plastic3DPrinter = new Printer3D(new PlasticPrinter());
      Printer paper3DPrinter = new Printer3D(new PaperPrinter());
      plasticPrinter.print();
      plastic3DPrinter.print();
      paper3DPrinter.print();
   }
}

示例图:

2016091003.png

门面(Facade)

门面模式隐藏了一个系统的复杂性,为使用者提供了一个简单的接口来与系 统交互。

情景分析

class ShapeFacade {
  interface Shape {
    void draw();//from   ww  w .  ja  v a  2s .co  m
  }
  class Rectangle implements Shape {
    @Override
    public void draw() {
      System.out.println("Rectangle::draw()");
    }
  }
  class Square implements Shape {
    @Override
    public void draw() {
      System.out.println("Square::draw()");
    }
  }
  class Circle implements Shape {
    @Override
    public void draw() {
      System.out.println("Circle::draw()");
    }
  }
  private Shape circle = new Circle();
  private Shape rectangle = new Rectangle();
  private Shape square = new Square();

  public ShapeFacade() {
  }
  public void drawCircle() {
    circle.draw();
  }
  public void drawRectangle() {
    rectangle.draw();
  }
  public void drawSquare() {
    square.draw();
  }
}
public class Main {
  public static void main(String[] args) {
    ShapeFacade shapeFacade = new ShapeFacade();
    shapeFacade.drawCircle();
    shapeFacade.drawRectangle();
    shapeFacade.drawSquare();
  }
}

享元(Flyweight)

使用共享来支持有效地支持大量细粒度的对象。

代理(Proxy)

在代理模式中,一个类代表另一个类的功能。在代理模式中,我们使用原始 的接口创建一个对象将功能暴露给外面世界。

情景分析

interface Printer {
   void print();/*ww  w  .  ja  v a 2  s  .  c  o  m*/
}
class ConsolePrinter implements Printer {
   private String fileName;

   public ConsolePrinter(String fileName){
      this.fileName = fileName;
   }
   @Override
   public void print() {
      System.out.println("Displaying " + fileName);
   }
}
class ProxyPrinter implements Printer{
   private ConsolePrinter consolePrinter;
   private String fileName;

   public ProxyPrinter(String fileName){
      this.fileName = fileName;
   }

   @Override
   public void print() {
      if(consolePrinter == null){
         consolePrinter = new ConsolePrinter(fileName);
      }
      consolePrinter.print();
   }
}
public class Main {

   public static void main(String[] args) {
      Printer image = new ProxyPrinter("test");
      image.print();   
   }
}

过滤器(Filter/Criteria Pattern)

Filter pattern filters objects using different criteria. The criteria can be chained together through logical operations.

情景分析

import java.util.List;
import java.util.ArrayList;
/*  w w  w.  j  a v  a2  s  .c  om*/
class Employee {
  private String name;
  private String gender;
  private String retireStatus;

  public Employee(String name, String gender, String r) {
    this.name = name;
    this.gender = gender;
    this.retireStatus = r;
  }

  public String getName() {
    return name;
  }

  public String getGender() {
    return gender;
  }

  public String getRetireStatus() {
    return retireStatus;
  }

  @Override
  public String toString() {
    return "Employee [name=" + name + ", gender=" + gender
        + ", retireStatus=" + retireStatus + "]";
  }
}

interface Criteria {
  public List<Employee> meetCriteria(List<Employee> persons);
}

class CriteriaMale implements Criteria {

  @Override
  public List<Employee> meetCriteria(List<Employee> persons) {
    List<Employee> malePersons = new ArrayList<Employee>();
    for (Employee person : persons) {
      if (person.getGender().equalsIgnoreCase("MALE")) {
        malePersons.add(person);
      }
    }
    return malePersons;
  }
}

class CriteriaFemale implements Criteria {

  @Override
  public List<Employee> meetCriteria(List<Employee> persons) {
    List<Employee> femalePersons = new ArrayList<Employee>();
    for (Employee person : persons) {
      if (person.getGender().equalsIgnoreCase("FEMALE")) {
        femalePersons.add(person);
      }
    }
    return femalePersons;
  }
}

class CriteriaRetire implements Criteria {

  @Override
  public List<Employee> meetCriteria(List<Employee> persons) {
    List<Employee> singlePersons = new ArrayList<Employee>();
    for (Employee person : persons) {
      if (person.getRetireStatus().equalsIgnoreCase("YES")) {
        singlePersons.add(person);
      }
    }
    return singlePersons;
  }
}

class AndCriteria implements Criteria {

  private Criteria criteria;
  private Criteria otherCriteria;

  public AndCriteria(Criteria criteria, Criteria otherCriteria) {
    this.criteria = criteria;
    this.otherCriteria = otherCriteria;
  }

  @Override
  public List<Employee> meetCriteria(List<Employee> persons) {
    List<Employee> firstCriteriaPersons = criteria.meetCriteria(persons);
    return otherCriteria.meetCriteria(firstCriteriaPersons);
  }
}

class OrCriteria implements Criteria {

  private Criteria criteria;
  private Criteria otherCriteria;

  public OrCriteria(Criteria criteria, Criteria otherCriteria) {
    this.criteria = criteria;
    this.otherCriteria = otherCriteria;
  }

  @Override
  public List<Employee> meetCriteria(List<Employee> persons) {
    List<Employee> firstCriteriaItems = criteria.meetCriteria(persons);
    List<Employee> otherCriteriaItems = otherCriteria.meetCriteria(persons);

    for (Employee person : otherCriteriaItems) {
      if (!firstCriteriaItems.contains(person)) {
        firstCriteriaItems.add(person);
      }
    }
    return firstCriteriaItems;
  }
}

public class Main {
  public static void main(String[] args) {
    List<Employee> persons = new ArrayList<Employee>();

    persons.add(new Employee("Tom", "Male", "YES"));
    persons.add(new Employee("Jack", "Male", "NO"));
    persons.add(new Employee("Jane", "Female", "NO"));
    persons.add(new Employee("Diana", "Female", "YES"));
    persons.add(new Employee("Mike", "Male", "NO"));
    persons.add(new Employee("Bob", "Male", "YES"));

    Criteria male = new CriteriaMale();
    Criteria female = new CriteriaFemale();
    Criteria retire = new CriteriaRetire();
    Criteria retireMale = new AndCriteria(retire, male);
    Criteria retireOrFemale = new OrCriteria(retire, female);

    System.out.println("Males: ");
    printPersons(male.meetCriteria(persons));

    System.out.println("Females: ");
    printPersons(female.meetCriteria(persons));

    System.out.println("Retire Males: ");
    printPersons(retireMale.meetCriteria(persons));

    System.out.println("Retire Or Females: ");
    printPersons(retireOrFemale.meetCriteria(persons));
  }

  public static void printPersons(List<Employee> persons) {
    for (Employee person : persons) {
      System.out.println(person);
    }
  }
}

行为模式

主要关注对象之间的交互。主要有如下一些具体模式:

责任链(Chain of Responsibility)

责任链模式为一个请求创建了一系列的接收者对象。通常在使用这种模式时, 每个接收者包含对另一个接收者的引用,形成一个引用链。 如果某个对象 不能使用当前请求,它可以交给下一个接收者去使用。

情景分析

abstract class Logger {
   protected Logger nextLogger;
/* w w w.  j  av  a2 s .  c  om*/
   public void setNextLogger(Logger nextLogger){
      this.nextLogger = nextLogger;
   }

   public void logMessage(String message){
      log(message);
      if(nextLogger !=null){
         nextLogger.logMessage(message);
      }
   }
   abstract protected void log(String message);  
}

class ConsoleLogger extends Logger {
   public ConsoleLogger(){
   }
   @Override
   protected void log(String message) {    
      System.out.println("Console::Logger: " + message);
   }
}
class EMailLogger extends Logger {
   public EMailLogger(){
   }
   @Override
   protected void log(String message) {    
      System.out.println("EMail::Logger: " + message);
   }
}
class FileLogger extends Logger {
   public FileLogger(){
   }
   @Override
   protected void log(String message) {    
      System.out.println("File::Logger: " + message);
   }
}
public class Main {  
   private static Logger getChainOfLoggers(){
      Logger emailLogger = new EMailLogger();
      Logger fileLogger = new FileLogger();
      Logger consoleLogger = new ConsoleLogger();
      emailLogger.setNextLogger(fileLogger);
      fileLogger.setNextLogger(consoleLogger);
      return emailLogger;  
   }
   public static void main(String[] args) {
      Logger loggerChain = getChainOfLoggers();
      loggerChain.logMessage("Null pointer");
      loggerChain.logMessage("Array Index Out of Bound");
      loggerChain.logMessage("Illegal Parameters");
   }
}

2016092710.png

命令(Command)

命令模式是一种数据驱动的模式,请求被封装成一个命令对象,传递给调 用者,调用者将相应的命令传递给相应的对象去执行。

情景分析

import java.util.ArrayList;
import java.util.List;
//ww w . j av  a2  s .  c o  m
interface Command {
  void execute();
}

class MouseCursor {
  private int x = 10;
  private int y = 10;
  public void move() {
    System.out.println("Old Position:"+x +":"+y);
    x++;
    y++;
    System.out.println("New Position:"+x +":"+y);

  }

  public void reset() {
    System.out.println("reset");
    x = 10;
    y = 10;
  }
}

class MoveCursor implements Command {
  private MouseCursor abcStock;

  public MoveCursor(MouseCursor abcStock) {
    this.abcStock = abcStock;
  }

  public void execute() {
    abcStock.move();
  }
}

class ResetCursor implements Command {
  private MouseCursor abcStock;

  public ResetCursor(MouseCursor abcStock) {
    this.abcStock = abcStock;
  }

  public void execute() {
    abcStock.reset();
  }
}

class MouseCommands {
  private List<Command> orderList = new ArrayList<Command>();

  public void takeOrder(Command order) {
    orderList.add(order);
  }

  public void placeOrders() {
    for (Command order : orderList) {
      order.execute();
    }
    orderList.clear();
  }
}

public class Main {
  public static void main(String[] args) {
    MouseCursor cursor = new MouseCursor();

    MoveCursor moveCursor = new MoveCursor(cursor);
    ResetCursor resetCursor = new ResetCursor(cursor);

    MouseCommands commands= new MouseCommands();
    commands.takeOrder(moveCursor);
    commands.takeOrder(resetCursor);

    commands.placeOrders();
  }
}

解释器(Interpreter)

通常解析器模式用于解析语言或表达式。

interface Expression {
  public boolean evaluate(String context);
}/*from  ww w  .ja v  a  2 s  .  com*/

class IsInExpression implements Expression {
  private String data;

  public IsInExpression(String data) {
    this.data = data;
  }

  @Override
  public boolean evaluate(String context) {
    if (context.contains(data)) {
      return true;
    }
    return false;
  }
}

class OrExpression implements Expression {

  private Expression expr1 = null;
  private Expression expr2 = null;

  public OrExpression(Expression expr1, Expression expr2) {
    this.expr1 = expr1;
    this.expr2 = expr2;
  }

  @Override
  public boolean evaluate(String context) {
    return expr1.evaluate(context) || expr2.evaluate(context);
  }
}

class AndExpression implements Expression {

  private Expression expr1 = null;
  private Expression expr2 = null;

  public AndExpression(Expression expr1, Expression expr2) {
    this.expr1 = expr1;
    this.expr2 = expr2;
  }

  @Override
  public boolean evaluate(String context) {
    return expr1.evaluate(context) && expr2.evaluate(context);
  }
}

public class Main {

  public static void main(String[] args) {
    Expression select = new IsInExpression("Select");
    Expression from = new IsInExpression("From");
    Expression isSelectFrom = new AndExpression(select, from);

    Expression insert = new IsInExpression("Insert");
    Expression update = new IsInExpression("Update");
    Expression isInsertOrUpdate = new OrExpression(insert, update);

    System.out.println(isSelectFrom.evaluate("Select"));
    System.out.println(isInsertOrUpdate.evaluate("Insert"));

    System.out.println(isSelectFrom.evaluate("Select From"));
    System.out.println(isInsertOrUpdate.evaluate("Update"));
  }
}

迭代器(Iterator)

在不了解对象底层细节的情况下,按顺序访问一组对象。

interface Iterator {
   public boolean hasNext();
   public Object next();
}/*  www  . ja v  a 2 s . c  o  m*/
class LetterBag {
   public String names[] = {"R" , "J" ,"A" , "L"};
   public Iterator getIterator() {
      return new NameIterator();
   }
   class NameIterator implements Iterator {
      int index;
      @Override
      public boolean hasNext() {
         if(index < names.length){
            return true;
         }
         return false;
      }
      @Override
      public Object next() {
         if(this.hasNext()){
            return names[index++];
         }
         return null;
      }    
   }
}
public class Main {
   public static void main(String[] args) {
      LetterBag bag = new LetterBag();
      for(Iterator iter = bag.getIterator(); iter.hasNext();){
         String name = (String)iter.next();
         System.out.println("Name : " + name);
      }   
   }
}

仲裁者(Mediator)

这个模式降低了多个对象间的通信。该模式提供了一个仲裁类处理不同对 象间的所有通信。

情景分析

class Printer {/*w w  w  .jav a2  s  . c  om*/
   public static void showMessage(Machine user, String message){
      System.out.println(new java.util.Date().toString()
         + " [" + user.getName() +"] : " + message);
   }
}
class Machine {
   private String name;

   public Machine(String name){
      this.name  = name;
   }
   public String getName() {
      return name;
   }
   public void setName(String name) {
      this.name = name;
   }
   public void sendMessage(String message){
      Printer.showMessage(this,message);
   }
}
class Main {
   public static void main(String[] args) {
      Machine m1= new Machine("M1");
      Machine m2 = new Machine("M2");

      m1.sendMessage("Rebooting");
      m2.sendMessage("Computing");
   }
}

备忘录(Memento)

The memento pattern is a software design pattern that provides the ability to restore an object to its previous state (undo via rollback).

备忘录模式有三个对象: Originator, Caretaker, memento。 Originator是拥有内部状态的一些对象, Caretaker首先向Originator要 一个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(this.state);
    }

    public void restoreFromMemento(Memento memento) {
        this.state = memento.getSavedState();
        System.out.println("Originator: State after restoring from Memento: " + state);
    }

    public static class Memento {
        private final String state;

        public Memento(String stateToSave) {
            state = stateToSave;
        }

        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)

当一个对象发生变化时,该模式用于通知所有这个对象依赖的对象。

import java.util.ArrayList;
import java.util.List;
/*from   w  ww .j  ava2  s  .  co m*/
class MyValue {
   private List<Observer> observers 
      = new ArrayList<Observer>();
   private int state;

   public int getState() {
      return state;
   }

   public void setState(int state) {
      this.state = state;
      notifyAllObservers();
   }

   public void attach(Observer observer){
      observers.add(observer);    
   }

   public void notifyAllObservers(){
      for (Observer observer : observers) {
         observer.update();
      }
   }   
}
abstract class Observer {
   protected MyValue subject;
   public abstract void update();
}
class PrinterObserver extends Observer{
   public PrinterObserver(MyValue subject){
      this.subject = subject;
      this.subject.attach(this);
   }

   @Override
   public void update() {
      System.out.println("Printer: " + subject.getState() ); 
   }
}
class EmailObserver extends Observer{

   public EmailObserver(MyValue subject){
      this.subject = subject;
      this.subject.attach(this);
   }

   @Override
   public void update() {
     System.out.println("Email: "+ subject.getState() ); 
   }
}
class FileObserver extends Observer{

   public FileObserver(MyValue subject){
      this.subject = subject;
      this.subject.attach(this);
   }

   @Override
   public void update() {
      System.out.println("File: " + subject.getState()); 
   }
}

public class Main {
   public static void main(String[] args) {
      MyValue subject = new MyValue();

      new FileObserver(subject);
      new EmailObserver(subject);
      new PrinterObserver(subject);

      subject.setState(15);

      subject.setState(10);
   }
}

状态(State)

在该模式下,一个类的行为会随状态的变化而改变。当使用状态模式时, 会创建各种状态下的对象以及一个上下文对象,它的行为随着状态对象的 变化而变化。

要点:

  1. You have a fixed set of states that the machine can be in.
  2. The machine can only be in one state at a time.
  3. A sequence of inputs or events is sent to the machine.
  4. Each state has a set of transitions, each associated with an input and pointing to a state.
interface Statelike {

    void writeName(StateContext context, String name);

}

class StateLowerCase implements Statelike {

    @Override
    public void writeName(final StateContext context, final String name) {
        System.out.println(name.toLowerCase());
        context.setState(new StateMultipleUpperCase());
    }

}

class StateMultipleUpperCase implements Statelike {
    /** Counter local to this state */
    private int count = 0;

    @Override
    public void writeName(final StateContext context, final String name) {
        System.out.println(name.toUpperCase());
        /* Change state after StateMultipleUpperCase's writeName() gets invoked twice */
        if(++count > 1) {
            context.setState(new StateLowerCase());
        }
    }

}

class StateContext {
    private Statelike myState;
    StateContext() {
        setState(new StateLowerCase());
    }

    /**
     * Setter method for the state.
     * Normally only called by classes implementing the State interface.
     * @param newState the new state of this context
     */
    void setState(final Statelike newState) {
        myState = newState;
    }

    public void writeName(final String name) {
        myState.writeName(this, name);
    }
}

public class DemoOfClientState {
    public static void main(String[] args) {
        final StateContext sc = new StateContext();

        sc.writeName("Monday");
        sc.writeName("Tuesday");
        sc.writeName("Wednesday");
        sc.writeName("Thursday");
        sc.writeName("Friday");
        sc.writeName("Saturday");
        sc.writeName("Sunday");
    }
}

策略(Strategy)

在策略模式下,我们会创建代表不同算法的对象,以及另一个上下文对象 来运行不同的算法。

interface MathAlgorithm {
   public int calculate(int num1, int num2);
}//from   w w w  . jav  a  2s .  c  om
class MathAdd implements MathAlgorithm{
   @Override
   public int calculate(int num1, int num2) {
      return num1 + num2;
   }
}
class MathSubstract implements MathAlgorithm{
   @Override
   public int calculate(int num1, int num2) {
      return num1 - num2;
   }
}
class MathMultiply implements MathAlgorithm{
   @Override
   public int calculate(int num1, int num2) {
      return num1 * num2;
   }
}
class MathContext {
   private MathAlgorithm algorithm;

   public MathContext(MathAlgorithm strategy){
      this.algorithm = strategy;
   }

   public int execute(int num1, int num2){
      return algorithm.calculate(num1, num2);
   }
}
public class Main {
   public static void main(String[] args) {
      MathContext context = new MathContext(new MathAdd());    
      System.out.println("10 + 5 = " + context.execute(10, 5));

      context = new MathContext(new MathSubstract());    
      System.out.println("10 - 5 = " + context.execute(10, 5));

      context = new MathContext(new MathMultiply());    
      System.out.println("10 * 5 = " + context.execute(10, 5));
   }
}

模板方法(Template Method)

在模板方法中,父类定义了一些提供给子类继承的抽象方法,另外,定义 了一个公共方法利用上述的抽象方法来实现一个业务逻辑。子类只需要关 注实现不同的业务逻辑步骤。

abstract class UseSoftware{
   abstract void download();
   abstract void install();
   abstract void configuration();
   abstract void run();

   public void useNewSoftware(){
     download();
     install();
     configuration();
     run();   
   }
}

访问者(Visitor Method)

在访问者模式中,元素对象接受一个访问者对象,访问者对象自理针对元 素对象的一些操作。 不同的访问者,可以针对元素对象采用不同的算法。

class TreeNode {/* w  ww  . j a  v a 2s  .  c  om*/
  private String name;
  public TreeNode(String name) {
    this.name = name;
  }
  public String getName() {
    return name;
  }
  public void accept(NodeVisitor v) {
    v.visit(this);
  }
}
interface NodeVisitor {
  public void visit(TreeNode n);
}
class ConsoleVisitor implements NodeVisitor {
  @Override
  public void visit(TreeNode n) {
    System.out.println("console:" + n.getName());
  }
}

class EmailVisitor implements NodeVisitor {
  @Override
  public void visit(TreeNode n) {
    System.out.println("email:" + n.getName());
  }
}

public class Main {
  public static void main(String[] args) {

    TreeNode computer = new TreeNode("Java2s.com");
    computer.accept(new ConsoleVisitor());
    computer.accept(new EmailVisitor());
  }
}

体系结构模式

MVC(Model-View-Controller)

扩展

Null Object pattern

在空对象模式中,创建一个无任何业务逻辑意义的对象来代替真正的空对象。 使用这个空业务逻辑对象来代表空指针检查。

abstract class AbstractEmployee {
   protected String name;
   public abstract boolean isNull();
   public abstract String getName();
}/*w  ww. j  a  v a2  s.c o m*/
class Programmer extends AbstractEmployee {
   public Programmer(String name) {
      this.name = name;    
   }
   @Override
   public String getName() {
      return name;
   }
   @Override
   public boolean isNull() {
      return false;
   }
}
class NullCustomer extends AbstractEmployee {
   @Override
   public String getName() {
      return "Not Available";
   }

   @Override
   public boolean isNull() {
      return true;
   }
}
class EmployeeFactory {
   public static final String[] names = {"Rob", "Joe", "Jack"};
   public static AbstractEmployee getCustomer(String name){
      for (int i = 0; i < names.length; i++) {
         if (names[i].equalsIgnoreCase(name)){
            return new Programmer(name);
         }
      }
      return new NullCustomer();
   }
}
public class Main {
   public static void main(String[] args) {

      AbstractEmployee emp = EmployeeFactory.getCustomer("Rob");
      AbstractEmployee emp2 = EmployeeFactory.getCustomer("Bob");
      AbstractEmployee emp3 = EmployeeFactory.getCustomer("Jack");
      AbstractEmployee emp4 = EmployeeFactory.getCustomer("Tom");

      System.out.println(emp.getName());
      System.out.println(emp2.getName());
      System.out.println(emp3.getName());
      System.out.println(emp4.getName());
   }
}

Service Provider

研究类ImageIO

Reactor pattern

Java Selector no blocking I/O

Proactor pattern

Java Asynchronous I/O