Vespers and Lauds

Vespers

The two major hours vary a good deal more with day and season than the minor hours do, but for just that reason their component parts tend to be more complicated and the high level classes are relatively simple.  Consider Vespers:

class Vespers

{

public:

  Vespers(const SpecialDays inDay, const Days inDayOfWeek);

  Vespers(const IHoursInfo& inHoursInfo, const IVespersInfo& inVespersInfo);

  void formatOffice(const IEncapsulatedOfficeFormatter &inFormatter,

               const IPsalter &inPsalter, const bool inRomanUse,

               const bool inIsPriest, const IHymnSource &inHymns);

private:

  VespersPsalmSpec m_psalms;

  VespersAntiphons m_antiphons;

  VespersChapter m_chapter;

  MagnificatAntiphons m_mag;

  std::unique_ptr<FerialPetitions> m_petitions;

  std::string m_collect;

  SpecialDays m_sd;

  Grades m_grade;

  HymnSeasons m_season;

};

Aside from the SpecialDays constructor, as always the home of a lot of detail to handle special cases:

Vespers::Vespers(const SpecialDays inDay, const Days inDayOfWeek)

    : m_psalms(inDay), m_antiphons(inDay), m_chapter(inDay),

      m_mag(inDay, inDayOfWeek),

      m_petitions(std::make_unique<FerialPetitions>(

        (inDay == SpecialDays::MAUNDY_THURSDAY) ? SpecialDays::GOOD_FRIDAY

                                                : inDay)),

      m_sd(inDay), m_grade(Grades::DOUBLE_FIRST_CLASS)

{

  if ((inDay == SpecialDays::MAUNDY_THURSDAY)

      || (inDay == SpecialDays::GOOD_FRIDAY))

    {

      m_collect

          = "Almighty God, we beseech thee graciously to behold this thy family, for which our Lord Jesus Christ was contented to be betrayed, and given up into the hands of wicked men, and to suffer death upon the Cross.";

      m_season = HymnSeasons::PASSIONTIDE;

    }

  else if (inDay == SpecialDays::HOLY_SATURDAY)

    {

      m_collect

          = "Grant, O Lord, that as we are baptised into the death of Thy blessed Son our Saviour Jesus Christ, so by continual mortifying our corrupt affections we may be buried with Him : and that through the grave and gate of death, we may pass to our joyful resurrection ; for His merits, who died, and was buried, and rose again for us, Thy Son Jesus Christ our Lord. Amen.";

      m_season = HymnSeasons::EASTER;

    }

  else

    {

      m_collect

          = "Almighty God, Who through Thy Only-begotten Son Jesus Christ hast overcome death, and opened unto us the gate of everlasting life ; we humbly beseech Thee, that, as by Thy special grace preventing us Thou dost put into our minds good desires, so by Thy continual help we may bring the same to good effect; through Jesus Christ our Lord.";

      m_season = HymnSeasons::EASTER;

    }

}

 -- note that because the Triduum starts on Thursaday evening we tell the Ferial Petitions (which change at that point, but not before) to behave as though it is good Friday -- both the principal constructor:

Vespers::Vespers(const IHoursInfo &inHoursInfo,

                 const IVespersInfo &inVespersInfo)

    : m_psalms(inVespersInfo.generatePsalmSpec()),

      m_antiphons(inVespersInfo.generateAntiphons()),

      m_chapter(inVespersInfo.generateChapter()),

      m_mag(inVespersInfo.generateMagnificatAntiphons()),

      m_petitions(inHoursInfo.generateFerialPetitions(OfficeNames::VESPERS)),

      m_collect(inHoursInfo.getCollect()), m_sd(SpecialDays::NONE),

      m_grade(inHoursInfo.grade()), m_season(inHoursInfo.getSeason())

{ }

and formatting function:

void Vespers::formatOffice(const IEncapsulatedOfficeFormatter &inFormatter,

     const IPsalter &inPsalter, const bool inRomanUse,

     const bool inIsPriest, const IHymnSource &inHymns)

{

  inFormatter.formatHeading("VESPERS");


  if ((m_sd != SpecialDays::MAUNDY_THURSDAY)

      && (m_sd != SpecialDays::GOOD_FRIDAY)

      && (m_sd != SpecialDays::HOLY_SATURDAY))

    {

      if (m_sd == SpecialDays::EASTER_WEEK)

  inFormatter.formatKyrie(false);

      else

inFormatter.formatInvocation(inRomanUse,

     (m_season == HymnSeasons::SEPTUAGESIMA)

     || (m_season == HymnSeasons::LENT)

     || (m_season == HymnSeasons::MID_LENT)

     || (m_season == HymnSeasons::PASSIONTIDE));

    }

  m_psalms.outputPsalms(inFormatter, m_antiphons, inPsalter);

  m_chapter.formatChapter(inFormatter, inHymns, m_season);

  m_mag.formatAntiphon(inFormatter, 0);

  m_petitions->formatPetitions(inFormatter, inPsalter, inRomanUse,

   inIsPriest);

  inFormatter.formatCollect(m_collect);

  inFormatter.formatDismissal(inIsPriest);

}

are fairly straightforward.

Lauds is much the same as Vespers:

class Lauds

{

public:

  Lauds(const IHoursInfo &inInfo, const ILaudsInfo &inLaudsInfo,

        const Days inDay);


  Lauds(const IPsalter &inPsalter, const SpecialDays inSpecialDay, const Days inDay);


  void formatOffice(const IEncapsulatedOfficeFormatter &inFormatter,

                    const bool inRomanUse,

                    const bool inIsPriest, const IHymnSource &inHymns) const;


private:

  LaudsInvocation m_invocation;

  LaudsPsalmSpec m_psalms;

  LaudsAntiphons m_antiphons;

  LaudsChapter m_chapter;

  BenedictusAntiphons m_benedictus;

  FerialPetitions m_petitions;

  std::string m_collect;

  HymnSeasons m_season;

  const IPsalter &m_psalter;

};

Lauds::Lauds(const IHoursInfo &inInfo, const ILaudsInfo &inLaudsInfo,

             const Days inDay)

    : m_invocation(inLaudsInfo.generateLaudsInvocation()),

      m_psalms(inLaudsInfo.generateLaudsPsalmSpec()),

      m_antiphons(inLaudsInfo.generateLaudsAntiphons()),

      m_chapter(inLaudsInfo.generateLaudsChapter()),

      m_benedictus(inLaudsInfo.generateBenedictusAntiphons()),

      m_petitions(inInfo.grade(), inDay, inInfo.getSeason(),

                  OfficeNames::LAUDS),

      m_collect(inInfo.getCollect()), m_season(inInfo.getSeason()),

      m_psalter(inLaudsInfo.getPsalter())

{

}


Lauds::Lauds(const IPsalter &inPsalter, const SpecialDays inSpecialDay, const Days inDay)

  : m_invocation(inSpecialDay), m_psalms(inPsalter, inSpecialDay, inDay),

      m_antiphons(inSpecialDay, inDay),

      m_chapter(inSpecialDay), m_benedictus(inSpecialDay, inDay),

      m_petitions(inSpecialDay),

      m_season((inSpecialDay == SpecialDays::EASTER_WEEK)

                   ? HymnSeasons::EASTER

                   : HymnSeasons::PASSIONTIDE),

      m_psalter(inPsalter)

{

  if (inSpecialDay == SpecialDays::EASTER_WEEK)

    m_collect

        = "Almighty God, Who through Thine Only-begotten Son Jesus Christ hast overcome death, and opened unto us the gate of everlast- ing life : we humbly beseech Thee, that as by Thy special grace preventing us. Thou dost put into our minds good desires, so by Th}^ continual help we may bring the same to good effect ; through Jesus Christ our Lord, Who liveth and reigneth with Thee and the Holy Ghost, ever one God, world without end. Amen.";

  else

    m_collect

        = "Almighty God, we beseech thee graciously to behold this thy family, for which our Lord Jesus Christ was contented to be betrayed, and given up into the hands of wicked men, and to suffer death upon the Cross.";

}

void

Lauds::formatOffice(const IEncapsulatedOfficeFormatter &inFormatter,

                    const bool inRomanUse,

                    const bool inIsPriest, const IHymnSource &inHymns) const

{

  inFormatter.formatHeading("LAUDS");

  m_invocation.format(inFormatter, inRomanUse);

  m_psalms.outputPsalms(inFormatter, m_antiphons, m_psalter);

  m_chapter.formatChapter(inFormatter, inHymns, m_season);

  m_benedictus.formatAntiphon(inFormatter, 0);

  m_petitions.formatPetitions(inFormatter, m_psalter, inRomanUse, inIsPriest);

  inFormatter.formatCollect(m_collect);

  inFormatter.formatDismissal(inIsPriest);

}

You will notice two types of interfaces being used as parameters in the constructors and formatting functions.  Some of them represent what I might call "normal" parameters: IHoursInfo and ILaudsInfo carry parameter information into the function, and IEncapsulatedOfficeFormatter is a local resource being used for a purpose, in a quasi-visitor way.

But IPsalter and IHymnSource belong to a different category: they represent resources allocated once and for all at the beginning of the application and passed around as general resources.  They are, in fact, examples of dependency injection. (Some people think that dependency injection is restricted to the type that makes use of external frameworks like Swing to manage it from configuration files.  Dependency injection is real in C++, but it has to be managed manually.)

Comments

Popular posts from this blog

Boundaries

State Machines

Considerations on an Optimization