且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

【愚公系列】2021年12月 通用职责分配原则(九)-受保护变量原则(Protected Variations Principle)

更新时间:2022-05-12 16:59:15

文章目录

前言

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

二、使用步骤

示例

前言

GRASP:General Responsibility Assignment Software Patterns 通用职责分配软件模式。


首先我们先来区分下GRASP与GOF模式的区别,它们主要在什么时候用,用来做什么。在软件开发过程中,我们常说面向对象开发,面向对象思想应该贯穿整个软件开发生命周期。我们在将现实世界中的业务对象及业务功能抽象成软件系统中的系统对象过程中应该遵循使用GRASP模式。而在具体技术实现上应该遵循使用GOF设计模式,来实现系统功能。即GRASP主要使用在分析设计阶段,与具体技术无关;而GOF模式主要使用在开发阶段,与具体技术相关,它是对GRASP设计成果进行实现时而使用,是一种开发阶段的设计模式。


GRASP软件设计模式包括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#设计模式 系列博文中行为型模式下的观察者模式中找到。