通用职责分配软件原则之9-受保护变量原则

受保护变量原则(Protected Variations Principle)


(1)问题

如何分配职责给对象、子系统和系统,使得这些元素中的变化或不稳定的点不会对其他元素产生不利影响?

(2)方案

找出预计有变化或不稳定的元素,为其创建稳定的“接口”而分配职责。

(3)分析

受保护变化模式简称PV,它是大多数编程和设计的基础,是模式的基本动机之一,它使系统能够适应和隔离变化。它与面向对象设计原则中的开闭原则相对应,即在不修改原有元素(类、模块、子系统或系统)的前提下扩展元素的功能。开闭原则又可称为“可变性封装原则(Principle of Encapsulation of Variation, EVP)”,要求找到系统的可变因素并将其封装起来。如将抽象层的不同实现封装到不同的具体类中,而且EVP要求尽量不要将一种可变性和另一种可变性混合在一起,这将导致系统中类的个数急剧增长,增加系统的复杂度。在具体实现时,为了符合受保护变化模式,我们通常需要对系统进行抽象化设计,定义系统的抽象层,再通过具体类来进行扩展。如果需要扩展系统的行为,无须对抽象层进行任何改动,只需要增加新的具体类来实现新的业务功能即可,在不修改已有代码的基础上扩展系统的功能。大多数设计原则和GoF模式都是受保护变化模式的体现。


示例:

public abstract class Publisher {
 
    private List<IReader> _readers = new List<IReader>();
 
    public string Name { get; set; }
    private const string LINE_BREAK =
        "----------------------------------------" +
        "----------------------------------------";
    //文章排版需要,故折成2行
 
    public void AttachReader(IReader reader) {
        if (reader == null) throw new ArgumentNullException();
        _readers.Add(reader);
    }
 
    public bool DetachReader(IReader reader) {
        if (reader == null) throw new ArgumentNullException();
        return _readers.Remove(reader);
    }
 
    protected virtual void OnPublish(Book book, DateTime publishTime) {
        Console.WriteLine(
            $"{Name} published {book.BookName()} at {publishTime.ToString("yyyy-MM-dd")}.");
        Console.WriteLine(LINE_BREAK);
    }
 
    public void Publish(Book book, DateTime publishTime) {
        OnPublish(book, publishTime);
        foreach (var reader in _readers) {
            if (reader != null) {
                reader.Receive(this, book);
            }
        }
        Console.WriteLine(LINE_BREAK);
    }
 
}

以上代码可在我的 C#设计模式 系列博文中行为型模式下的观察者模式中找到。

猜你喜欢

转载自blog.csdn.net/qq_31116753/article/details/81259813