代码改变世界

细胞自动机项目中观察者模式的解析

2018-10-23 15:35  东东东东东  阅读(283)  评论(0编辑  收藏  举报

一、项目简介

用Java实现的一个小游戏,一个网格代表一个细胞,一个网格周围有8个网格,如果某活细胞周围活着的邻居的数量<2或>3,则该细胞死亡;如果死细胞周围刚好有3个邻居或者,则该死细胞获得新生。

二、观察模式简介

观察者模式(Observer)完美的将观察者和被观察的对象分离开。举个例子,用户界面可以作为一个观察者,业务数据是被观察者,用户界面观察业务数据的变化,发现数据变化后,就显示在界面上。面向对象设计的一个原则是:系统中的每个类将重点放在某一个功能上,而不是其他方面。一个对象只做一件事情,并且将他做好。观察者模式在模块之间划定了清晰的界限,提高了应用程序的可维护性和重用性。

三、观察者模式实例—细胞自动机

   1、观察者模式图

 

 

2、被观察者分析

被观察者是一个field类,里面有此时所有细胞的状态,即为数据。

 

package field;

import java.util.ArrayList;

import cell.Cell;

public class Field {
    private int width;
    private int height;
    private Cell[][] field;
    
    public Field(int width, int height) {
        this.width = width;
        this.height = height;
        field = new Cell[height][width];
    }
    
    public int getWidth() { return width; }
    public int getHeight() { return height; }
    
    public Cell place(int row, int col, Cell o) {
        Cell ret = field[row][col];
        field[row][col] = o;
        return ret;
    }
    
    public Cell get(int row, int col) {
        return field[row][col];
    }
    
    public Cell[] getNeighbour(int row, int col) {
        ArrayList<Cell> list = new ArrayList<Cell>();
        for ( int i=-1; i<2; i++ ) {
            for ( int j=-1; j<2; j++ ) {
                int r = row+i;
                int c = col+j;
                if ( r >-1 && r<height && c>-1 && c<width && !(r== row && c == col) ) {
                    list.add(field[r][c]);
                }
            }
        }
        return list.toArray(new Cell[list.size()]);
    }
    
    public void clear() {
        for ( int i=0; i<height; i++ ) {
            for ( int j=0; j<width; j++ ) {
                field[i][j] = null;
            }
        }
    }
}

3、观察者分析

观察者是一个view类,他只有一个paint功能,即将此时field里的数据画出来。

 

package field;

import java.awt.Dimension;
import java.awt.Graphics;

import javax.swing.JFrame;
import javax.swing.JPanel;

import cell.Cell;

public class View extends JPanel {
    private static final long serialVersionUID = -5258995676212660595L;
    private static final int GRID_SIZE = 16;
    private Field theField;
    
    public View(Field field) {
        theField = field;
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        for ( int row = 0; row<theField.getHeight(); row++ ) {
            for ( int col = 0; col<theField.getWidth(); col++ ) {
                Cell cell = theField.get(row, col);
                if ( cell != null ) {
                    cell.draw(g, col*GRID_SIZE, row*GRID_SIZE, GRID_SIZE);
                }
            }
        }
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(theField.getWidth()*GRID_SIZE+1, theField.getHeight()*GRID_SIZE+1);
    }

    public static void main(String[] args) {
        Field field = new Field(10,10);
        for ( int row = 0; row<field.getHeight(); row++ ) {
            for ( int col = 0; col<field.getWidth(); col++ ) {
                field.place(row, col, new Cell());
            }
        }
        View view = new View(field);
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setResizable(false);
        frame.setTitle("Cells");
        frame.add(view);
        frame.pack();
        frame.setVisible(true);
    }

}

4、观察者模式的优点

  观察者模式可以实现表示层和数据逻辑层的分离,定义了稳定的消息更新传递机制,并抽象了更新接口,使得可以有各种各样不同的表示层充当具体观察者角色。 一个抽象模型有两个方面,其中一个方面依赖于另一个方面,将这两个方面封装在独立的对象中使它们可以各自独立地改变和复用。