5

行为型模式(四)

 3 years ago
source link: https://segmentfault.com/a/1190000039946154
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

行为型模式到这篇就结束了,完了之后是结构型模式。

空对象模式

这个模式可以说用得比较少,至少再我真正学习之前是没有用过的,甚至没有听过的。在空对象模式中,一个空对象取代NULL对象实例的检查。NULL对象不是检查控制,而是反应一个不做任何动作的关系。

AbstractClass: 抽象出来的对象,具有一定的逻辑

RealClass: 真正的对象

NullObject: 空对象

空对象UML

空对象模式

AbstractClass

public abstract class AbstractClass {
    public abstract void print();
    public abstract void isNullObject();
}

RealClass

public class RealClass extends AbstractClass {
    @Override
    public void print() {
        System.out.println("real class: hello world");
    }

    @Override
    public void isNullObject() {
        System.out.println("i am real object");
    }
}

NullClass

public class NullClass extends AbstractClass {
    @Override
    public void print() {
        System.out.println("do nothing");
    }

    @Override
    public void isNullObject() {
        System.out.println("do nothing");
    }
}

为了方便演示,还增加了一个工厂类用来随机生成是RealClass 还是NullClass

ObjectFactory

public class ObjectFactory {
    public static AbstractClass getObjectClass() {
        if (Math.random() * 10 > 4) {
            return new RealClass();
        }
        return new NullClass();
    }
}

Client

public class Client {
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            ObjectFactory.getObjectClass().isNullObject();
            ObjectFactory.getObjectClass().print();
        }
    }
}

就是这么朴实无华,但是确实是用得比较少,上网一搜甚至很多标题都是被遗弃的设计模式。

访问者模式

访问者模式的目的是要把处理从数据结构中分离出来,其优点是增加新的操作很容易,因为增加新的操作就以为着增加一个新的访问者。

通俗地来说,把数据抽象成一类,把操作抽象成一类。拿王者荣耀举例,最典型的就是英雄算是数据,玩家就是访问者,新增一个玩家只需要新增一个具体访问者即可。

Element: 抽象出来的元素,里面有个accept方法来接受访问者的访问,对应例子就是英雄的抽象类

Concrete Element: 具体的元素,对应就是具体的某个英雄

Visitor: 访问者,一般需要包含访问所有具体元素的抽象方法,对应游戏就是玩家的抽象类

Concrete Element: 具体的访问者,对应到例子就是不同的具体的玩家

访问者UML

访问者模式

Visitor

public abstract class VisitorPlayer {
    public abstract void visit(ConcreteElementGuangYu guangYu);
    public abstract void visit(ConcreteElementMaKe maKe);
}

Element

public abstract class ElementHero {
    public abstract void accept(VisitorPlayer visitorPlayer);

    public void normalAttack() {
        System.out.println("浦东公鸡");
    }
    public abstract void firstSkill();
    public abstract void secondSkill();
    public abstract void thirdSkill();
}

ConcreteElement

public class ConcreteElementGuangYu extends ElementHero{
    @Override
    public void accept(VisitorPlayer visitorPlayer) {
        System.out.println("您已选择英雄");
        visitorPlayer.visit(this);
    }


    @Override
    public void firstSkill() {
        System.out.println("单刀赴会");
    }

    @Override
    public void secondSkill() {
        System.out.println("青龙偃月");
    }

    @Override
    public void thirdSkill() {
        System.out.println("刀锋铁骑");
    }
}
public class ConcreteElementMaKe extends ElementHero{
    @Override
    public void accept(VisitorPlayer visitorPlayer) {
        System.out.println("您已经选择该英雄");
        visitorPlayer.visit(this);
    }

    @Override
    public void firstSkill() {
        System.out.println("华丽左轮");
    }

    @Override
    public void secondSkill() {
        System.out.println("漫游之枪");
    }

    @Override
    public void thirdSkill() {
        System.out.println("狂热弹幕");
    }
}

ConcreteVisitor

public class ConcreteVisitorPlayerA extends VisitorPlayer{

    @Override
    public void visit(ConcreteElementGuangYu guangYu) {
        guangYu.thirdSkill();
        guangYu.secondSkill();
        guangYu.normalAttack();
        guangYu.normalAttack();
        guangYu.normalAttack();
        guangYu.firstSkill();
    }

    @Override
    public void visit(ConcreteElementMaKe maKe) {
        maKe.secondSkill();
        maKe.firstSkill();
        maKe.normalAttack();
        maKe.normalAttack();
        maKe.thirdSkill();
    }
}
public class ConcreteVisitorPlayerB extends VisitorPlayer {
    @Override
    public void visit(ConcreteElementGuangYu guangYu) {
        guangYu.normalAttack();
        guangYu.normalAttack();
        guangYu.firstSkill();
        guangYu.normalAttack();
    }

    @Override
    public void visit(ConcreteElementMaKe maKe) {
        maKe.secondSkill();
        maKe.firstSkill();
        maKe.normalAttack();
        maKe.firstSkill();
        maKe.secondSkill();
    }
}

为了更方便使用,一般还有有一个ObjectStructure 类,这个类主要是为了构建结构关系的

ObjectStructure

public class ObjectStructure {
    private List<ElementHero> elementHeroes = new ArrayList<>();

    public void attach(ElementHero hero) {
        elementHeroes.add(hero);
    }

    public void detach(ElementHero hero) {
        elementHeroes.remove(hero);
    }

    public void accept(VisitorPlayer player) {
        for (ElementHero elementHero : elementHeroes) {
            elementHero.accept(player);
        }
    }

}

Client

public class Client {
    public static void main(String[] args) {
        ObjectStructure objectStructure = new ObjectStructure();
        objectStructure.attach(new ConcreteElementGuangYu());
        objectStructure.attach(new ConcreteElementMaKe());

        ConcreteVisitorPlayerA concreteVisitorPlayerA = new ConcreteVisitorPlayerA();
        ConcreteVisitorPlayerB concreteVisitorPlayerB = new ConcreteVisitorPlayerB();

        System.out.println("玩家A开始操作");
        objectStructure.accept(concreteVisitorPlayerA);
        System.out.println("玩家B开始操作");
        objectStructure.accept(concreteVisitorPlayerB);

    }
}

知识就在那里,差距就是有的人学了有的人没学。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK