NVIï¼Non virtual Interface
ãNVIï¼Non Virtual Interfaceï¼ã£ã¦ããåãã§ããï¼ å®è£ è¨è¨ã«ããããªã¹ã¹ã¡ã®ããªã·ã¼/ã¹ã¿ã¤ã«ã®ä¸ã¤ãªãã§ããã©ããããªé£ãã話ããããã¾ãããå¹³ããè¨ãã°ããããªãã¯ã¡ã½ãããvirtualã«ããªããã¨ããå®è£ ä¸ã®å¶ç´ã§ããããã£ã¦ä½ããªã¤ã·ã¤ãã§ãããã
ãæ¥ä»ãæ±ãã¢ããªã±ã¼ã·ã§ã³ã®ãã¡é¨åã¨ãã¦ããããªã®ãèãã¾ããï¼
class DateUtil { public: const char* dayOfWeek(int nday) const; /* nday ã§ä¸ãããã 0,1...6 ã«å¯¾ãããããã * "æ¥æ","ææ" ... "åæ" ãè¿ã */ ... }; const char* DateUtil::dayOnWeek(int nday) const { switch ( nday ) { case 0 : return "æ¥æ"; case 1 : return "ææ"; ... case 6 : return "åæ"; default: return nullptr; }
ãã©ãã«ã§ããããããªãã©ã£ã¦ãã¨ã®ãªãã³ã¼ãã§ããæ¥æ¬èªã ãã§ãªãè±èªã«ã対å¿ãã¾ãããã
class DateUtil_ja { public: const char* dayOfWeek(int nday) const; /* "æ¥æ","ææ" ... "åæ" ãè¿ã */ ... }; class DateUtil_en { public: const char* dayOfWeek(int nday) const; /* "Sun","Mon" ... "Sat" ãè¿ã */ ... };
ãã¯ã¼ã«ãã¯ã¤ããªå¸å ´ãçã£ãã¢ããªã±ã¼ã·ã§ã³ã®é¨åãªããããã¾ããããã¡ãªã¹ããã¯ã§ãããã
ãã¦ã¼ã¶ã®ã好ã¿ãlocaleã®è¨å®æ¬¡ç¬¬ã§æ¥/è±ãã³ãã³ãåãæ¿ããããªããã£ã¨ï¼
enum class language { ja, en }; class DateUtil { // åºåºã¯ã©ã¹ public: virtual const char* dayOfWeek(int nday) const=0; static DateUtil* create(language lang); ... }; class DateUtil_ja : public DateUtil { public: virtual const char* dayOfWeek(int nday) const; /* "æ¥æ","ææ" ... "åæ" ãè¿ã */ ... }; class DateUtil_en : public DateUtil { public: virtual const char* dayOfWeek(int nday) const; /* "Sun","Mon" ... "Sat" ãè¿ã */ ... }; DateUtil* DateUtil::create(language lang) { switch ( lang ) { case language::ja : return new Dateutil_ja(); case language::en : return new Dateutil_ja(); default: return nulllptr; }
ãã¾ããã¾ãã¾ã妥å½ãªãã¶ã¤ã³ã§ããããã
ãããã§NVIãé©ç¨ãã¾ããNVIã¯ããããªãã¯ã¡ã½ãããvirtualã«ããªãããã«ã¼ã«ãªã®ã§ãdayOfWeek()ãvirtualã«ã§ãã¾ããããããã©ããããã£ã¤ã¼ã¨ãvirtualä»®æ³é¢æ°å¼ã³åºãã®ããã«ã¯ã³ã¯ãã·ã§ã³ç½®ããã§ããï¼
class DateUtil { // åºåºã¯ã©ã¹ public: const char* dayOfWeek(int nday) const { return do_dayOfWeek(nday); // dayOfWeekã®"æ¬ä½"ãå¼ã¶ } static DateUtil* create(language lang); protected: virtual const char* do_dayOfWeek(int nday) const =0; ... }; class DateUtil_ja : public DateUtil { protected: virtual const char* do_dayOfWeek(int nday) const; /* "æ¥æ","ææ" ... "åæ" ãè¿ã */ ... }; class DateUtil_en : public DateUtil { protected: virtual const char* do_dayOfWeek(int nday) const; /* "Sun","Mon" ... "Sat" ãè¿ã */ ... };
ãåçã«å·®ãæ¿ããvirtualé¢æ°ãprotectedé¨ã«ç½®ããpublicãªé¢æ°ããããã¤ãå¼ã³åºããã¨ã§å®è£ ãã¦ãã¾ãããã®ã¾ã¾protectedãªdo_dayOfWeek()ã«ä¸¸æã/横æµãã§ããããã³ã¼ããç¡é§ã«ãããããããã ãã«è¦ãã¾ãã
- ãåããããªå¦çããã¡ãã¡ã«ãã©æãããï¼Code Cloneï¼ãã¨ãé¿ãããã
- ãã¤ã³ã¿ã¼ãã§ã¼ã¹ã®å¤æ´ãå®è£ ã«åã¼ãå½±é¿ãå°ããæãããã
ãå®ç¾ããã¹ã¿ã¤ã«ã®ä¸ã¤ãNVIã§ãã
ãpublicé¨ã«ã¡ã½ãããç½®ãã¨ãããã¨ã¯ããªãã¡ã"使ã人"ã«ã¤ã³ã¿ã¼ãã§ã¼ã¹ãæä¾ãããã¨ãæå³ãã¾ããããã¨åæã«ãã®ã¡ã½ããã"ä½ã人"ã«å ¥åºåã®ä»æ§ãè¦å®ãããã¨ã«ãªãã¾ãã
ããã®ä¸¡è ãå¼·ãçµã³ã¤ãã¦ããã¨ä¸æ¹ã®å¤æ´ãä»æ¹ã«å½±é¿ãåã¼ãã¾ãããã®ãã¨èªä½ã¯virtualã§ãªãã¡ã½ããã§ãåããã¨ãªã®ã§ãããvirtualã¡ã½ããã®ã¤ã³ã¿ã¼ãã§ã¼ã¹ã®å¤æ´ã¯ãããåå®ç¾©ãã¦ãããã¹ã¦ã®ç®æã«ç´¯ãåã¶ã®ã§ãå½±é¿ç¯å²ãããåºããã¤é大ã§ãã
ãä¾ãã°ãããªä»æ§å¤æ´ï¼
ããdayOfWeek(int nday)ã ãã©ããndayã0ï½6以å¤ã ã£ããdomain_errorä¾å¤ãæãã¦ãããªãï¼ã
ãdayOfWeek()ãvirtualã§ãåå°åºã¯ã©ã¹ã§åå®ç¾©ããã¦ããããã®å¤æ´ã¯å°åºã¯ã©ã¹ãã¹ã¦ã«ããã³ã¾ãããã®å¤æ´ã身å ã®ä¸ã ããªãã¾ã ãããã§ããã©ãã¨ã¼ãããæ¯é¨ã®ãã©ã³ã¹/ãã¤ã対å¿ãã¼ã ãDateUtilããDateUtil_fr/DateUtil_deãå°åºãã¦ãã...
ãNVIãªãã°å¤æ´ç®æã¯åºåºã¯ã©ã¹ã®ä¸ç®æã ãã
const char* DateUtil::dayOfWeek(int nday) const { if ( nday < 0 || nday > 6 ) { throw std::domain_error("invalid day-number"); } return do_dayOfWeek(nday); // dayOfWeekã®"æ¬ä½"ãå¼ã¶ }
ããã¤ãã§ã«ndayã¯1ï½7ã§ãé¡ããå¦çä¸ã¯CriticalSectionã§ã¬ã¼ããã¦ãããã§ãã£ã¦æ»ãå¤ã¯std::stringã«ãã¦ãããªãã
std::string DateUtil::dayOfWeek(int nday, CriticalSection* cs) const { if ( nday < 1 || nday > 7 ) { throw std::domain_error("invalid day-number"); } EntrCriticalSection(cs); std::string result = do_dayOfWeek(nday-1); // dayOfWeekã®"æ¬ä½"ãå¼ã¶ EntrCriticalSection(cs); return result; }
ãã¡ãã£ã¨ãã工夫ãªãã ãã©ãã¯ã©ã¹ã»ããªã¼ã®æèã®å¤ãæ§é ã§ãã£ããªãããªãã®å¹æãæå¾ ã§ãã¾ããã