设计模式--对享元模式的思考

来源:互联网 发布:阿里域名价格 编辑:程序博客网 时间:2024/05/21 16:22

享元模式:利用共享技术实现大量细粒度的对象(即状态不会发生改变的对象)的重用。

功能:实现大量相同或者是相似的对象的重用。

实现享元模式的关键是正确的区分对象的内部状态和外部状态。内部状态就是不会随环境的变化而变化,是可以被共享的部分。外部状态就是会随环境的变化而变化的状态,是不可以被共享的部分。当在使用享元对象的时候只需要将外部状态传到内部状态即可。

下面是相关实例:

下面是一个围棋游戏的设计。

分析知道围棋有很多颗,如果把每个都看成一个实例的话,就会占用太多的内存空间,浪费了内存资源。此时的话采用享元模式来设计的话会比较好。

内部状态:围棋的颜色(黑色和白色)。(不会因为环境的变化而变化)

外部状态:围棋的位置。(会随环境的变化而变化)

实现享元模式:

1.      抽象的享元类或接口:AbstractChess

2.      具体的享元类:BlackChess、WhiteChess

3.      享元类依赖的类:Position

4.      创建享元类实例的工厂:ChessFactory

下面是相关实现:

AbstractChess.java

public abstract class AbstractChess {

    public abstract String getColor();

    public void display(Position position){

       System.out.println("棋子的颜色:"+this.getColor()+",横坐标X="+

              position.getX()+",纵坐标Y="+position.getY());

    }

}

BlackChess.java

public class BlackChess extendsAbstractChess{

    public String getColor() {

       return"黑色";

    }  

}

WhiteChess.java

public class WhiteChess extendsAbstractChess{

    public String getColor() {

       return"白色";

    }

}

Position.java

public class Position {

    private int x;//定义围棋所在的横坐标

    private int y;//定义围棋所在的纵坐标

    public Position(int x,int y) {

       super();

       this.x = x;

       this.y = y;

    }

    public int getX() {

       returnx;

    }

    public void setX(int x) {

       this.x = x;

    }

    public int getY() {

       returny;

    }

    public void setY(int y) {

       this.y = y;

    }

}

 

ChessFactory.java

public class ChessFactory {

    //工厂采用单例来设计

    private static final ChessFactory FACTORY = new ChessFactory();

    private static HashMap<String, AbstractChess> hm;//定义享元池

    static

    {

       hm = new HashMap<String, AbstractChess>();

       hm.put("black",new BlackChess());

       hm.put("white",new WhiteChess());

    }

    private ChessFactory(){}

    public static ChessFactory getInstance()

    {

       returnFACTORY;

    }

    public AbstractChess getChess(String key)

    {

       returnhm.get(key);

    }

}

Client.java

public class Client {

    public static void main(String[] args) {

       ChessFactory factory = ChessFactory.getInstance();

       AbstractChess chess1 = factory.getChess("black");

       AbstractChess chess2 = factory.getChess("black");

       AbstractChess chess3 = factory.getChess("black");

       AbstractChess chess4 = factory.getChess("white");

       AbstractChess chess5 = factory.getChess("white");

       System.out.println(chess1==chess2);

       System.out.println(chess1==chess3);

       System.out.println(chess1==chess4);

       System.out.println(chess4==chess5);

       chess1.display(new Position(0,0));

       chess2.display(new Position(0,1));

       chess3.display(new Position(0,2));

       chess4.display(new Position(1,2));

       chess5.display(new Position(2,4));

    }

}

结果:

true

true

false

true

棋子的颜色:黑色,横坐标X=0,纵坐标Y=0

棋子的颜色:黑色,横坐标X=0,纵坐标Y=1

棋子的颜色:黑色,横坐标X=0,纵坐标Y=2

棋子的颜色:白色,横坐标X=1,纵坐标Y=2

棋子的颜色:白色,横坐标X=2,纵坐标Y=4

通过结果很显然能够看出围棋棋子对象得到了重用

0 0