设计模式 | 策略模式(行为型)

实现方式

  • 同步划分:同步阻塞、异步非阻塞
  • 线程划分:线程内的、跨线程的

原理及应用场景

观察者模式(Observer Design Pattern)也被称为发布订阅模式(Publish-Subscribe Design Pattern),它的定义是这样的:
在对象之间定义一个一对多的依赖,当一个对象状态改变的时候,所有依赖的对象都会自动收到通知。
核心概念: 被观察者、观察者 Subject、Observer Producer、Consumer EventEmitter、EventListener Dispatcher、Listener
实现一个一对一的依赖
//在对象之间定义一个一对多的依赖,当一个对象状态改变的时候,所有依赖的对象都会自动收到通知。

public class Class1
    {
        public static void Main(string[] args)
        {
            Subject subject = new Subject();
            subject.notify();
        }
    }
    public  class Subject{
        private static Observer observer = new Observer();
        public void notify() {
            observer.update();
        }
    }
    public class Observer
    {
        public void update()
        {
            Console.WriteLine("观察者更新行为被触发");
        }
    }

最经典的实现方式

   public class Class1
    {
        public static void Main(string[] args)
        {
            Subject subject = new Subject();
            subject.RegisterObserver(new ObserverA());
            subject.RegisterObserver(new ObserverB());
            subject.notifyObserver(null);
        }
    }
    public  class Subject{
        private static List<Observer> list = new List<Observer>();
        public void RegisterObserver(Observer observer) {
            list.Add(observer);
        }
        public void RemoveObserver(Observer observer) {
            list.Remove(observer);
        }
        public void notifyObserver(Message message) {
            foreach (var item in list)
            {
                item.update(message);
            }
        }
    }
    public class Message {
        public string content;
    }
    public interface Observer
    {
        void update(Message message);
    }
    public class ObserverA:Observer
    {
        public void update(Message message)
        {
            Console.WriteLine("观察者A更新行为被触发");
        }
    }
    public class ObserverB: Observer
    {
        public void update(Message message)
        {
            Console.WriteLine("观察者B更新行为被触发");
        }
    }

案例: 假设我们在开发一个 P2P 投资理财系统,用户注册成功之后,我们会给用户发放投资体验金。代码实现大致是下面这个样子的:

public class UserController
    {
        private IUserService userService;
        private IPromotionService promotionService;
        public UserController(IUserService userService, IPromotionService promotionService)
        {
            this.userService = userService;
            this.promotionService = promotionService;
        }
        public long register(string telephone, string password)
        { 
            //省略输入参数的校验代码 
            //省略userService.register()异常的try-catch代码
            long userId = userService.register(telephone, password);
            promotionService.issueNewUserExperienceCash(userId);
            return userId;
        }
    }
    public interface IUserService {
        long register(string telephone, string password);
    }
    public interface IPromotionService {
        void issueNewUserExperienceCash(long userId);
    }

虽然注册接口做了两件事情,注册和发放体验金,违反单一职责原则,但是,如果没有扩展和修改的需求,现在的代码实现是可以接受的。如果非得用观察者模式,就需要引入更多的类和更加复杂的代码结构,反倒是一种过度设计。
相反,如果需求频繁变动,比如,用户注册成功之后,不再发放体验金,而是改为发放优惠券,并且还要给用户发送一封“欢迎注册成功”的站内信。这种情况下,我们就需要频繁地修改 register() 函数中的代码,违反开闭原则。而且,如果注册成功之后需要执行的后续操作越来越多,那 register() 函数的逻辑会变得越来越复杂,也就影响到代码的可读性和可维护性。
这个时候,观察者模式就能派上用场了。利用观察者模式,我对上面的代码进行了重构。重构之后的代码如下所示:

    public class UserController
    {
        private IUserService userService;
        private List<RegObserver> regObservers = new List<RegObserver>();
        public UserController(IUserService userService)
        {
            this.userService = userService;
        }
        public void setRegObservers(List<RegObserver> observers) { regObservers.AddRange(observers); }
        public long register(string telephone, string password)
        { 
            //省略输入参数的校验代码 
            //省略userService.register()异常的try-catch代码
            long userId = userService.register(telephone, password);
            foreach (RegObserver item in regObservers)
            {
                item.handleRegSuccess(userId);
            }
            return userId;
        }
    }
    public interface RegObserver {
        void handleRegSuccess(long userId);
    }
    public class RegNotificationObserver : RegObserver
    {
        public void handleRegSuccess(long userId)
        {
            throw new NotImplementedException();
        }
    }
    public class RegPromotionObserver : RegObserver
    {
        private IPromotionService promotionService;
        public RegPromotionObserver(IPromotionService promotionService)
        {
            this.promotionService = promotionService;
        }
        public void handleRegSuccess(long userId)
        {
            promotionService.issueNewUserExperienceCash(userId);
        }
    }
    public interface IUserService {
        long register(string telephone, string password);
    }
    public interface IPromotionService {
        void issueNewUserExperienceCash(long userId);
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

靓仔很忙i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值