简介:

装璜器模式:动静地将责任附加到对象上。若要扩大性能,装璜者提供了比继承更有弹性的代替计划。比拟官网,上面通过例子来解释一下

我的利用场景(兴许不大适合),我写了一个坦克大战的小游戏,当初呢坦克能打出子弹,然而这个子弹比拟繁多不咋难看,如果我想在子弹下面加些装璜,那我是不是再加一个子弹类继承自游戏物体类,而后在这个新的子类当中画出新的子弹(比方给子弹加一个火花),那么如果当前有各种各样的千奇百怪的子弹呈现,我就会有无数个子类,那么无疑是要爆炸了,如下图

那么是否有其余方法,当然是有的,如下图,咱们定义一个一般子弹类(Bullet)。再定义一个装璜器GODecorator,其蕴含一个子弹对象,并能够对其进行“装璜”,这样一来咱们每多加一种装璜,只须要多装璜一次即可,防止了反复设计大量的类似类。这就是装璜器模式的利用

在类图中,各个角色的阐明如下:

GameObject,形象构件

  GameObject(游戏物体)是一个接口或者抽象类,是定义咱们最外围的对象,也能够说是最原始的对象。

Bullet,具体构件,或者根底构件

  Bullet(子弹)是最外围、最原始、最根本的接口或抽象类Component的实现,能够独自用,也可将其进行装璜。

GODecorator,形象装璜器角色

  个别是一个抽象类,继承自或实现GameObject,在它的属性外面有一个变量指向GameObject形象构件。

TailDecorator、RectDecorator,具体装璜器角色

  TailDecorator和RectDecorator是两个具体的装璜类,它们能够把根底构件装璜成新的货色,比方给子弹加个尾巴和方框。

解释比拟形象,咱们看看代码实现:

GameObject

package com.mashibing.tank;import java.awt.*;/** * 游戏物体的父类,无论是坦克,子弹,爆炸等等都继承自这个类 */public abstract class GameObject {    public int x, y; public abstract int getWidth(); public abstract int getHeight(); public abstract void paint(Graphics g);}

Bullet

package com.mashibing.tank;import java.awt.*;public class Bullet extends GameObject{    private static final int SPEED = ProperMgr.getInt("bulletSpeed"); public Rectangle rect = new Rectangle(); private Dir dir; public static int WIDTH = ResourceMgr.bulletD.getWidth(); public static int HEIGHT = ResourceMgr.bulletD.getHeight(); private boolean living = true; //子弹是否死掉,飞出窗口或者撞到敌人 public Group group = Group.BAD; public Bullet(int x, int y, Dir dir, Group group) {        this.x = x; this.y = y; this.dir = dir; this.group = group; rect.x = this.x; rect.y = this.y; rect.width = WIDTH; rect.height = HEIGHT; GameModel.getInstance().add(this); }    @Override public void paint(Graphics g) {        if(!living){            GameModel.getInstance().remove(this); }        switch (dir) {            case LEFT:                g.drawImage(ResourceMgr.bulletL,x,y,null); break; case UP:                g.drawImage(ResourceMgr.bulletU,x,y,null); break; case RIGHT:                g.drawImage(ResourceMgr.bulletR,x,y,null); break; case DOWN:                g.drawImage(ResourceMgr.bulletD,x,y,null); break; } move(); }    private void move() {        switch (dir) {            case LEFT:                x -= SPEED; break; case UP:                y -= SPEED; break; case RIGHT:                x += SPEED; break; case DOWN:                y += SPEED; break; }        rect.x = this.x; rect.y = this.y; if (x < 0 || y < 0 || x > TankFrame.GAME_WIDTH || y > TankFrame.GAME_HEIGHT) living = false; }    public void die() {        this.living = false; }    @Override public int getWidth() {        return WIDTH; }    @Override public int getHeight() {        return HEIGHT; }}

GODecorator

package com.mashibing.decorator;import com.mashibing.tank.GameObject;import java.awt.*;public abstract class GODecorator extends GameObject {    GameObject go; public GODecorator(GameObject go) {        this.go = go; }    @Override public abstract void paint(Graphics g);}

TailDecorator

package com.mashibing.decorator;import com.mashibing.tank.Bullet;import com.mashibing.tank.GameObject;import java.awt.*;public class TailDecorator extends GODecorator {    public TailDecorator(GameObject go) {        super(go); }    @Override public int getWidth() {        return super.go.getWidth(); }    @Override public int getHeight() {        return super.go.getHeight(); }    @Override public void paint(Graphics g) {        this.x = go.x; this.y = go.y; go.paint(g); System.out.println("tail:"+(go instanceof Bullet)); Color c = g.getColor(); g.setColor(Color.WHITE); g.drawLine(go.x,go.y,go.x + getWidth(), go.y+getHeight()); g.setColor(c); }}

RectDecorator

package com.mashibing.decorator;import com.mashibing.tank.Bullet;import com.mashibing.tank.GameObject;import java.awt.*;public class RectDecorator extends GODecorator {    public RectDecorator(GameObject go) {        super(go); }    @Override public int getWidth() {        return super.go.getWidth(); }    @Override public int getHeight() {        return super.go.getHeight(); }    @Override public void paint(Graphics g) {        this.x = go.x; this.y = go.y; go.paint(g); System.out.println("rect:"+(go instanceof TailDecorator)); Color c = g.getColor(); g.setColor(Color.WHITE); g.drawRect(go.x,go.y,go.getWidth(),go.getHeight()); g.setColor(c); }}

应用

public class DecoratorDemo{    public static void main(String[] args){        GameObject bullet = new Bullet();        // 第一次润饰,加个尾巴        component = new TailDecorator(component);        // 第二次润饰,加个方框        component = new RectDecorator(component);    }}

总结:这就是装璜器的应用,那个如果我还要给子弹换个色彩,加个色彩装璜器即可,另外这些具体的装璜器我还能够用来装璜其余的物体,比方坦克也能够加个框或者加个尾巴,间接应用雷同的装璜器即可,这样子就解决了继承带来的问题,比拟容易扩大