初探设计模式之【观察者】

初探设计模式之【观察者】

一、前言

在现实生活中,观察者往往是主动的、被观察者是被动的。比如,要小王要向领导汇报一件事情,因而时刻关注着领导的工位,看领导有没有来公司。如果领导一直不来,对于小王来说,可能有点烦,这领导也太不省心了…。我们可以这么做,小王事先与领导沟通,然后领导告诉小王说:”今天会晚一些,到公司了会告诉你“,那这样,小王就省心多了,不用一直盯着这件事。

相应的,在软件开发中,也有类似的场景,比如在电商业务中,用户想要购买某件商品,可是商品暂时无货了,着急的用户可能会每隔一个小时跑来这个商品的页面刷新,看是不是有货了,这就是一种观察者的主动行为,服务器作为被观察者是被动的,如果在大促期间这么做的用户非常多,不仅用户体验不好,服务器还要承受特别大的压力,对双方都不好。而如果产品经理在商详中增加了【订阅到货】功能(想购买的用户点击订阅商品到货通知,代商品到货后,通知所有订阅者),就可以解决这些弊端了。

二、实现

首先是观察者基类:

public abstract class Buyer {

    private String name;

    public Buyer(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public abstract void inform(Product product);

}

观察者的核心方法是一个抽象的通知方法,统一被观察者通知观察者的方式。

商品类:

public class Product {

    public String name;

    public int count;

    public Product() {
    }

    public Product(String name, int count) {
        this.name = name;
        this.count = count;
    }
}

然后我们实现一些观察者,这里是具体的买家

手机黄牛:(遇见手机,有多少买多少)

/**
 * 黄牛 专门倒卖手机 有多少收多少
 */
public class Vendor extends Buyer {

    public Vendor(String name) {
        super(name);
    }

    @Override
    public void inform(Product product) {
        if (product.name.contains("手机")) {
            if (product.count > 0) {
                System.out.println(getName() + "买光了" + product.count + "台" + product.name);
                product.count = 0;
            } else {
                System.out.println(getName() + ":" + product.name + "已经被抢购一空");
            }
        }
    }
}

手机爱好者:

public class PhoneBuyer extends Buyer {

    public PhoneBuyer(String name) {
        super(name);
    }

    @Override
    public void inform(Product product) {
        if (product.name.contains("手机")) {
            if (product.count > 0) {
                product.count--;
                System.out.println(getName() + "买了一台" + product.name);
            } else {
                System.out.println(getName() + ":" + product.name + "已经被抢购一空");
            }
        }
    }
}

爱读书的人:

public class Reader extends Buyer {

    public Reader(String name) {
        super(name);
    }

    @Override
    public void inform(Product product) {
        if (product.name.contains("书")) {
            if (product.count > 0) {
                product.count--;
                System.out.println(getName() + "买走了一本" + product.name);
            } else {
                System.out.println(getName() + ":" + product.name + "已经被抢购一空");
            }
        }
    }
}

购物狂,什么都买

public class Shopaholic extends Buyer {

    public Shopaholic(String name) {
        super(name);
    }

    @Override
    public void inform(Product product) {
        if (product.count > 0) {
            product.count--;
            System.out.println(getName() + "买了一个" + product.name);
        } else {
            System.out.println(getName() + ":" + product.name + "已经被抢购一空");
        }
    }
}

商店类:

public class Shop {

    private final List<Buyer> buyers = new ArrayList<>();

    private Product product;

    public void register(Buyer buyer) {
        if (!buyers.contains(buyer)) {
            buyers.add(buyer);
        }
    }

    public void unRegister(Buyer buyer) {
        buyers.remove(buyer);
    }

    public void setProduct(Product product) {
        this.product = product;
        notifyBuyers();
    }

    private void notifyBuyers() {
        for (Buyer buyer : buyers) {
            buyer.inform(product);
        }
    }
    
}

商店类维护了一个买家列表,商品到货后,通知所有买家,化被动为主动。

最后是调用处:

public static void main(String[] args) {
    Shop shop = new Shop();

    shop.register(new PhoneBuyer("果粉"));
    shop.register(new Reader("读书人"));
    shop.register(new Vendor("黄牛党"));
    shop.register(new Shopaholic("剁手党"));

    shop.setProduct(new Product("苹果手机", 100));

    System.out.println("==============");

    shop.setProduct(new Product("书:追风筝的人", 5));

    System.out.println("==============");

    shop.setProduct(new Product("大白菜", 100));

}

输入日志如下:

果粉买了一台苹果手机

黄牛党买光了99台苹果手机

剁手党:苹果手机已经被抢购一空

读书人买走了一本书:追风筝的人

剁手党买了一个书:追风筝的人

剁手党买了一个大白菜

三、总结

作为一种发布/订阅式模型,观察者模式被大量应用于具有一对多关系对象结构的场景,它支持多个观察者订阅一个目标主题。一旦目标主题的状态发生变化,目标对象便主动进行广播,即刻对所有订阅者发布全员消息通知。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值