±à¼ÍƼö: |
±¾ÎÄÊ×Ïȼòµ¥½éÉÜÒ»ÏÂʲôÊǸɾ»¼Ü¹¹£¨Clean architecture£©£¬±ÈÈçÁìÓò¡¢ÓÃÀýºÍÓ¦ÓòãÕâЩ¸ÅÄȻºó¾ÍÊÇÔõô°Ñ¸É¾»¼Ü¹¹Ó¦ÓÃÓÚǰ¶Ë£¬ÒÔ¼°Öµ²»ÖµµÃÕâô×ö¡£
½ÓÏÂÀ´£¬Óøɾ»¼Ü¹¹µÄÔÔòÀ´Éè¼ÆÒ»¸öÉ̵êÓ¦Ó㬲¢´ÓͷʵÏÖһϣ¬¿´¿´ËüÄܲ»ÄÜÔËÐÐÆðÀ´¡£
À´×ÔÓÚ51CTO ,ÓÉ»ðÁú¹ûÈí¼þLinda±à¼¡¢ÍƼö¡£ |
|
ǰ¶ËÓмܹ¹Âð£¿Õâ¿ÉÄÜÊǺܶàÈËÐÄÀïµÄÒÉ»ó£¬ÒòΪÔÚʵ¼ÊÒµÎñ¿ª·¢ÀïÎÒÃǺÜÉÙΪǰ¶ËÈ¥Éè¼Æ±ê×¼¹æ·¶µÄ´úÂë¼Ü¹¹£¬¿ÉÄܸü¶àµÄÈ¥¹Ø×¢µÄÊǹ¤³Ì»¯¡¢Ä¿Â¼²ã¼¶¡¢ÒÔ¼°ÒµÎñ´úÂëµÄʵÏÖ¡£
½ñÌìÎÒÃÇÀ´¿´Ò»ÖÖǰ¶Ë¼Ü¹¹µÄģʽ£¬Ô×÷Õß³ÆËüΪ¡°¸É¾»¼Ü¹¹£¨Clean Architecture£©¡±£¬ÎÄÕºܳ¤£¬½²µÄÒ²ºÜÏêϸ£¬ÎÒ»¨Á˺ܳ¤Ê±¼äÈ¥¶ÁÍêÁËËü£¬¿´ÍêºÜÓÐÊÕ»ñ£¬·Òë¸ø´ó¼Ò£¬ÎÄÖÐÒ²ÈÚÈëÁ˺ܶàÎÒ×Ô¼ºµÄ˼¿¼£¬ÍƼö´ó¼Ò¿´Íê¡£
https://dev.to/bespoyasov/clean-architecture-on-frontend-4311??
±¾ÎÄÖÐʾÀýµÄÔ´Â룺https://github.com/bespoyasov/frontend-clean-architecture/
Ê×ÏÈ£¬ÎÒÃÇ»á¼òµ¥½éÉÜÒ»ÏÂʲôÊǸɾ»¼Ü¹¹£¨Clean architecture£©£¬±ÈÈçÁìÓò¡¢ÓÃÀýºÍÓ¦ÓòãÕâЩ¸ÅÄȻºó¾ÍÊÇÔõô°Ñ¸É¾»¼Ü¹¹Ó¦ÓÃÓÚǰ¶Ë£¬ÒÔ¼°Öµ²»ÖµµÃÕâô×ö¡£
½ÓÏÂÀ´£¬ÎÒÃÇ»áÓøɾ»¼Ü¹¹µÄÔÔòÀ´Éè¼ÆÒ»¸öÉ̵êÓ¦Ó㬲¢´ÓͷʵÏÖһϣ¬¿´¿´ËüÄܲ»ÄÜÔËÐÐÆðÀ´¡£
Õâ¸öÓ¦Óý«Ê¹Óà React ×÷ΪËüµÄ UI ¿ò¼Ü£¬ÕâÖ»ÊÇΪÁ˱íÃ÷ÕâÖÖ¿ª·¢·½Ê½ÊÇ¿ÉÒÔºÍ React
Ò»ÆðʹÓõġ£ÄãÒ²¿ÉÒÔÑ¡ÔñÆäËûÈκÎÒ»ÖÖ UI ¿âȥʵÏÖËü¡£
´úÂëÖлáÓõ½Ò»Ð© TypeScript£¬ÕâÖ»ÊÇΪÁËչʾÔõôʹÓÃÀàÐͺͽӿÚÀ´ÃèÊöʵÌå¡£ÆäʵËùÓеĴúÂë¶¼¿ÉÒÔ²»ÓÃ
TypeScript ʵÏÖ£¬Ö»ÊÇ´úÂë²»»á¿´ÆðÀ´ÄÇô¸»ÓбíÏÖÁ¦¡£
¼Ü¹¹ºÍÉè¼Æ
Éè¼Æ±¾ÖÊÉϾÍÊÇÒÔÒ»ÖÖ¿ÉÒÔ½«ËüÃÇÖØÐÂ×éºÏÔÚÒ»ÆðµÄ·½Ê½½«ÊÂÎï²ð¿ª¡¡ ½«ÊÂÎï²ð·Ö³É¿ÉÒÔÖØÐÂ×éºÏµÄÊÂÎÕâ¾ÍÊÇÉè¼Æ¡£¡ª
Rich Hickey¡¶Éè¼Æ¡¢Öع¹ºÍÐÔÄÜ¡·
ϵͳÉè¼ÆÆäʵ¾ÍÊÇϵͳµÄ²ð·Ö£¬×îÖØÒªµÄÊÇÎÒÃÇ¿ÉÒÔÔÚ²»ºÄ·ÑÌ«¶àʱ¼äµÄÇé¿öÏÂÖØÐ°ÑËüÃÇ×éÆðÀ´¡£
ÎÒͬÒâÉÏÃæÕâ¸ö¹Ûµã£¬µ«ÎÒÈÏΪϵͳ¼Ü¹¹µÄÁíÒ»¸öÖ÷ҪĿ±êÊÇϵͳµÄ¿ÉÀ©Õ¹ÐÔ¡£ÎÒÃÇÓ¦ÓõÄÐèÇóÊDz»¶Ï±ä»¯µÄ¡£ÎÒÃÇÏ£ÍûÎÒÃǵijÌÐò¿ÉÒԷdz£Ò×ÓÚ¸üкÍÐÞ¸ÄÒÔÂú×ã³ÖÐø±ä»¯µÄÐÂÐèÇ󡣸ɾ»µÄ¼Ü¹¹¾Í¿ÉÒÔ°ïÖúÎÒÃÇʵÏÖÕâһĿ±ê¡£
ʲôÊǸɾ»µÄ¼Ü¹¹£¿
¸É¾»¼Ü¹¹ÊÇÒ»ÖÖ¸ù¾ÝÓ¦ÓóÌÐòµÄÁìÓò£¨domain£©µÄÏàËÆ³Ì¶ÈÀ´²ð·ÖÖ°ÔðºÍ¹¦Äܵķ½·¨¡£
ÁìÓò£¨domain£©ÊÇÓÉÕæÊµÊÀ½ç³éÏó¶øÀ´µÄ³ÌÐòÄ£ÐÍ¡£¿ÉÒÔ·´Ó³ÏÖʵÊÀ½çºÍ³ÌÐòÖÐÊý¾ÝµÄÓ³Éä¡£±ÈÈ磬Èç¹ûÎÒÃǸüÐÂÁËÒ»¸ö²úÆ·µÄÃû³Æ£¬ÓÃÐÂÃû³ÆÀ´Ìæ»»¾ÉÃû³Æ¾ÍÊÇÁìÓòת»»¡£
¸É¾»¼Ü¹¹µÄ¹¦ÄÜͨ³£±»·ÖΪÈý²ã£¬ÎÒÃÇ¿ÉÒÔ¿´ÏÂÃæÕâÕÅͼ£º

ÁìÓò²ã
ÔÚÖÐÐĵÄÊÇÁìÓò²ã£¬ÕâÀï»áÃèÊöÓ¦ÓóÌÐòÖ÷ÌâÇøÓòµÄʵÌåºÍÊý¾Ý£¬ÒÔ¼°×ª»»¸ÃÊý¾ÝµÄ´úÂë¡£ÁìÓòÊÇÇø·Ö²»Í¬³ÌÐòµÄºËÐÄ¡£
Äã¿ÉÒÔ°ÑÁìÓòÀí½âΪµ±ÎÒÃÇ´Ó React Ç¨ÒÆµ½ Angular£¬»òÕ߸ıäijЩÓÃÀýµÄʱºò²»»á±äµÄÄÇÒ»²¿·Ö¡£ÔÚÉ̵êÕâ¸öÓ¦ÓÃÖУ¬ÁìÓò¾ÍÊDzúÆ·¡¢¶©µ¥¡¢Óû§¡¢¹ºÎï³µÒÔ¼°¸üÐÂÕâЩÊý¾ÝµÄ·½·¨¡£
Êý¾Ý½á¹¹ºÍËûÃÇÖ®¼äµÄת»¯ÓëÍⲿÊÀ½çÊÇÏ໥¸ôÀëµÄ¡£ÍⲿµÄʼþµ÷Óûᴥ·¢ÁìÓòµÄת»»£¬µ«ÊDz¢²»»á¾ö¶¨ËûÃÇÈçºÎÔËÐС£
±ÈÈ磺½«ÉÌÆ·Ìí¼Óµ½¹ºÎï³µµÄ¹¦Äܲ¢²»¹ØÐÄÉÌÆ·Ìí¼Óµ½¹ºÎï³µµÄ·½Ê½£º
Óû§×Ô¼ºÍ¨¹ýµã»÷¡°¹ºÂò¡±°´Å¥Ìí¼Ó
Óû§Ê¹ÓÃÁËÓÅ»Ýȯ×Ô¶¯Ìí¼Ó¡£
ÔÚÕâÁ½ÖÖÇé¿öÏ£¬¶¼»á·µ»ØÒ»¸ö¸üÐÂÖ®ºóµÄ¹ºÎï³µ¶ÔÏó¡£
Ó¦Óòã
ΧÔÚÁìÓòÍâÃæµÄÊÇÓ¦Óò㣬ÕâÒ»²ãÃèÊöÁËÓÃÀý¡£
ÀýÈ磬¡°Ìí¼Óµ½¹ºÎï³µ¡±Õâ¸ö³¡¾°¾ÍÊÇÒ»¸öÓÃÀý¡£ËüÃèÊöÁ˵¥»÷°´Å¥ºóÓ¦Ö´ÐеľßÌå²Ù×÷£¬ÏñÊÇÒ»ÖÖ¡°Ðµ÷Õß¡±£º
Ïò·þÎñÆ÷·¢ËÍÒ»¸öÇëÇó£»
Ö´ÐÐÁìÓòת»»£»
ʹÓÃÏìÓ¦µÄÊý¾Ý¸üРUI¡£
´ËÍ⣬ÔÚÓ¦ÓòãÖл¹ÓÐ¶Ë¿Ú ¡ª ËüÃèÊöÁËÓ¦ÓòãÈçºÎºÍÍⲿͨÐÅ¡£Í¨³£Ò»¸ö¶Ë¿Ú¾ÍÊÇÒ»¸ö½Ó¿Ú£¨interface£©£¬Ò»¸öÐÐΪÆõÔ¼¡£
¶Ë¿ÚÒ²¿ÉÒÔ±»ÈÏΪÊÇÒ»¸öÏÖʵÊÀ½çºÍÓ¦ÓóÌÐòÖ®¼äµÄ¡°»º³åÇø¡±¡£ÊäÈë¶Ë¿Ú»á¸æËßÎÒÃÇÓ¦ÓÃÒªÈçºÎ½ÓÊÜÍⲿµÄÊäÈ룬ͬÑùÊä³ö¶Ë¿Ú»á˵Ã÷ÈçºÎÓëÍⲿͨÐÅ×öºÃ×¼±¸¡£
ÊÊÅäÆ÷²ã
×îÍâ²ã°üº¬ÁËÍⲿ·þÎñµÄÊÊÅäÆ÷£¬ÎÒÃÇͨ¹ýÊÊÅäÆ÷À´×ª»»Íⲿ·þÎñµÄ²»¼æÈÝ API¡£
ÊÊÅäÆ÷¿ÉÒÔ½µµÍÎÒÃǵĴúÂëºÍÍⲿµÚÈý·½·þÎñµÄñîºÏ£¬ÊÊÅäÆ÷Ò»°ã·ÖΪ£º
Çý¶¯ÐÍ - ÏòÎÒÃǵÄÓ¦Ó÷¢ÏûÏ¢£»
±»¶¯ÐÍ - ½ÓÊÜÎÒÃǵÄÓ¦ÓÃËù·¢Ë͵ÄÏûÏ¢¡£
Ò»°ãÓû§×î³£ºÍÇý¶¯ÐÍÊÊÅäÆ÷½øÐн»»¥£¬ÀýÈ磬´¦ÀíUI¿ò¼Ü·¢Ë͵ĵã»÷ʼþ¾ÍÊÇÒ»¸öÇý¶¯ÐÍÊÊÅäÆ÷¡£ËüÓëä¯ÀÀÆ÷
API Ò»Æð½«Ê¼þת»»ÎªÎÒÃǵÄÓ¦ÓóÌÐò¿ÉÒÔÀí½âµÄÐźš£
Çý¶¯ÐÍ»áºÍÎÒÃǵĻù´¡ÉèÊ©½»»¥¡£ÔÚǰ¶Ë£¬´ó²¿·ÖµÄ»ù´¡ÉèÊ©¾ÍÊǺó¶Ë·þÎñÆ÷£¬µ«ÓÐʱÎÒÃÇÒ²¿ÉÄÜ»áÖ±½ÓÓëÆäËûµÄһЩ·þÎñ½»»¥£¬ÀýÈçËÑË÷ÒýÇæ¡£
×¢Ò⣬ÀëÖÐÐÄÔ½Ô¶£¬´úÂëµÄ¹¦ÄܾÍÔ½ ¡°ÃæÏò·þÎñ¡±£¬ÀëÓ¦ÓõÄÁìÓò¾ÍÔ½Ô¶£¬ÕâÔÚºóÃæÎÒÃÇÒª¾ö¶¨Ò»¸öÄ£¿éÊÇÄÄÒ»²ãµÄʱºòÊǷdz£ÖØÒªµÄ¡£
ÒÀÀµ¹æÔò
Èý²ã¼Ü¹¹ÓÐÒ»¸öÒÀÀµ¹æÔò£ºÖ»ÓÐÍâ²ã¿ÉÒÔÒÀÀµÄڲ㡣ÕâÒâζ×Å£º
ÁìÓò±ØÐë¶ÀÁ¢
Ó¦Óòã¿ÉÒÔÒÀÀµÁìÓò
×îÍâ²ã¿ÉÒÔÒÀÀµÈκζ«Î÷

µ±È»ÓÐÐ©ÌØÊâµÄÇé¿ö¿ÉÄÜ»áÎ¥·´Õâ¸ö¹æÔò£¬µ«×îºÃ²»ÒªÀÄÓÃËü¡£ÀýÈ磬ÔÚÁìÓòÖÐÒ²ÓпÉÄÜ»áÓõ½Ò»Ð©µÚÈý·½¿â£¬¼´Ê¹²»Ó¦¸Ã´æÔÚÕâÑùµÄÒÀÀµ¹ØÏµ¡£ÏÂÃæ¿´´úÂëʱ»áÓÐÕâÑùÒ»¸öÀý×Ó¡£
²»¿ØÖÆÒÀÀµ·½ÏòµÄ´úÂë¿ÉÄÜ»á±äµÃ·Ç³£¸´ÔÓºÍÄÑÒÔά»¤¡£±ÈÈ磺
Ñ»·ÒÀÀµ£¬Ä£¿é A ÒÀÀµÓÚ B£¬B ÒÀÀµÓÚ C£¬C ÒÀÀµÓÚ A¡£
¿É²âÊÔÐԲ¼´Ê¹²âÊÔһС¿é¹¦ÄÜÒ²²»µÃ²»Ä£ÄâÕû¸öϵͳ¡£
ñîºÏ¶ÈÌ«¸ß£¬Òò´ËÄ£¿éÖ®¼äµÄ½»»¥»áºÜ´àÈõ¡£
¸É¾»¼Ü¹¹µÄÓÅÊÆ
¶ÀÁ¢ÁìÓò
ËùÓÐÓ¦ÓõĺËÐŦÄܶ¼±»²ð·Ö²¢Í³Ò»Î¬»¤ÔÚÒ»¸öµØ·½¡ªÁìÓò
ÁìÓòÖеŦÄÜÊǶÀÁ¢µÄ£¬ÕâÒâζ×ÅËü¸üÈÝÒײâÊÔ¡£Ä£¿éµÄÒÀÀµÔ½ÉÙ£¬²âÊÔËùÐèµÄ»ù´¡ÉèÊ©¾ÍÔ½ÉÙ¡£
¶ÀÁ¢µÄÁìÓòÒ²¸üÈÝÒ׸ù¾ÝÒµÎñµÄÆÚÍû½øÐвâÊÔ¡£ÕâÓÐÖúÓÚÈÃÐÂÊÖÀí½âÆðÀ´¸üÈÝÒס£´ËÍ⣬¶ÀÁ¢µÄÓòÒ²ÈôÓÐèÇóµ½´úÂëʵÏÖÖгöÏֵĴíÎó¸üÈÝÒ×Åųý¡£
¶ÀÁ¢ÓÃÀý
Ó¦ÓõÄʹÓó¡¾°ºÍÓÃÀý¶¼ÊǶÀÁ¢ÃèÊöµÄ¡£Ëü¾ö¶¨ÁËÎÒÃÇËùÐèÒªÄÄЩµÚÈý·½·þÎñ¡£ÎÒÃÇÈÃÍⲿ·þÎñ¸üÊÊÓ¦ÎÒÃǵÄÐèÇó£¬ÕâÈÃÎÒÃÇÓиü¶àµÄ¿Õ¼ä¿ÉÒÔÑ¡ÔñºÏÊʵĵÚÈý·½·þÎñ¡£±ÈÈ磬ÏÖÔÚÎÒÃǵ÷ÓõÄÖ§¸¶ÏµÍ³ÕǼÛÁË£¬ÎÒÃÇ¿ÉÒԺܿìµÄ»»µôËü¡£
ÓÃÀýµÄ´úÂëÒ²ÊÇ±âÆ½µÄ£¬²¢ÇÒÈÝÒײâÊÔ£¬À©Õ¹ÐÔÇ¿¡£ÎÒÃÇ»áÔÚºóÃæµÄʾÀýÖп´µ½ÕâÒ»µã¡£
¿ÉÌæ»»µÄµÚÈý·½·þÎñ
ÊÊÅäÆ÷ÈÃÍⲿµÚÈý·½·þÎñ¸üÈÝÒ×Ìæ»»¡£Ö»ÒªÎÒÃDz»¸Ä½Ó¿Ú£¬ÄÇôʵÏÖÕâ¸ö½Ó¿ÚµÄÊÇÄĸöµÚÈý·½·þÎñ¶¼Ã»¹ØÏµ¡£
ÕâÑùÈç¹ûÆäËûÈ˸͝ÁË´úÂ룬²»»áÖ±½ÓÓ°ÏìÎÒÃÇ¡£ÊÊÅäÆ÷Ò²»á¼õÉÙÓ¦ÓÃÔËÐÐʱ´íÎóµÄ´«²¥¡£
ʵÏָɾ»¼Ü¹¹µÄ³É±¾
¼Ü¹¹Ê×ÏÈÊÇÒ»ÖÖ¹¤¾ß¡£ÏñÈÎºÎÆäËû¹¤¾ßÒ»Ñù£¬¸É¾»µÄ¼Ü¹¹³ýÁ˺ô¦Ö®Í⻹»á´øÀ´¶îÍâµÄ³É±¾¡£
ÐèÒª¸ü¶àʱ¼ä
Ê×ÏÈÊÇʱ¼ä£¬Éè¼Æ¡¢ÊµÏÖ¶¼ÐèÒª¸ü¶àµÄʱ¼ä£¬ÒòΪֱ½Óµ÷ÓõÚÈý·½·þÎñ×ÜÊDZÈдÊÊÅäÆ÷¼òµ¥¡£
ÎÒÃǺÜÄÑÔÚÒ»¿ªÊ¼¾Í°ÑÄ£¿éËùÓеĽ»»¥ºÍÐèÇó¶¼ÏëµÄºÜÃ÷°×£¬ÎÒÃÇÉè¼ÆµÄʱºòÐèҪʱ¿ÌÁôÒâÄÄЩµØ·½¿ÉÄÜ·¢Éú±ä»¯£¬ËùÒÔÒª¿¼ÂǸü¶àµÄ¿ÉÀ©Õ¹ÐÔ¡£
ÓÐʱ»áÏԵöàÓà
Ò»°ãÀ´Ëµ£¬¸É¾»¼Ü¹¹²¢²»ÊÊÓÃÓÚËùÓг¡¾°¡¢ÉõÖÁÓеÄʱºòÊÇÓк¦µÄ¡£Èç¹û±¾Éí¾ÍÊÇÒ»¸öºÜСµÄÏîÄ¿£¬Ä㻹Ҫ°´Õոɾ»¼Ü¹¹½øÐÐÉè¼Æ£¬Õâ»á´ó´óÔö¼ÓÉÏÊÖÃż÷¡£
ÉÏÊÖ¸üÀ§ÄÑ
ÍêÈ«°´Õոɾ»¼Ü¹¹½øÐÐÉè¼ÆºÍʵÏÖ»áÈÃÐÂÊÖÉÏÊÖ¸ü¼ÓÀ§ÄÑ£¬ÒòΪËûÊ×ÏÈÒªÁ˽âÇå³þÓ¦ÓÃÊÇÔõôÔËÐÐÆðÀ´µÄ¡£
´úÂëÁ¿Ôö¼Ó
ÕâÊÇǰ¶Ë»áÌØÓеÄÒ»¸öÎÊÌ⣬¸É¾»¼Ü¹¹»áÔö¼Ó×îÖÕ´ò°üµÄ²úÎïÌå»ý¡£²úÎïÔ½´ó£¬ä¯ÀÀÆ÷ÏÂÔØºÍ½âÊ͵Äʱ¼äÔ½³¤£¬ËùÒÔ´úÂëÁ¿Ò»¶¨Òª°Ñ¿ØºÃ£¬Êʵ±É¾¼õ´úÂ룺
½«ÓÃÀýÃèÊöµÄµÃ¸ü¼òµ¥Ò»Ð©£»
Ö±½Ó´ÓÊÊÅäÆ÷ºÍÁìÓò½»»¥£¬ÈƹýÓÃÀý£»
½øÐдúÂë²ð·Ö
ÈçºÎ½µµÍÕâЩ³É±¾
Äã¿ÉÒÔͨ¹ýÊʵ±µÄ͵¹¤¼õÁϺÍÎþÉü¼Ü¹¹µÄ¡°¸É¾»¶È¡±À´¼õÉÙһЩʵÏÖʱ¼äºÍ´úÂëÁ¿¡£Èç¹ûÉáÆúһЩ¶«Î÷»á»ñµÃ¸ü´óµÄÊÕÒæ£¬ÎÒ»áºÁ²»ÓÌÔ¥µÄÈ¥×ö¡£
ËùÒÔ£¬²»±ØÔÚËùÓз½Ãæ×ß×ñÊØ¸É¾»¼Ü¹¹µÄÉè¼Æ×¼Ôò£¬°ÑºËÐÄ×¼Ôò×ñÊØºÃ¼´¿É¡£
³éÏóÁìÓò
¶ÔÁìÓòµÄ³éÏó¿ÉÒÔ°ïÖúÎÒÃÇÀí½âÕûÌåµÄÉè¼Æ£¬ÒÔ¼°ËüÃÇÊÇÔõô¹¤×÷µÄ£¬Í¬Ê±Ò²»áÈÃÆäËû¿ª·¢ÈËÔ±¸üÈÝÒ×Àí½â³ÌÐò¡¢ÊµÌåÒÔ¼°ËüÃÇÖ®¼äµÄ¹ØÏµ¡£
¼´Ê¹ÎÒÃÇÖ±½ÓÌø¹ýÆäËû²ã£¬³éÏóµÄÁìÓòÒ²¸ü¼ÓÈÝÒ×ÖØ¹¹¡£ÒòΪËüÃǵĴúÂëÊǼ¯Öзâ×°ÔÚÒ»¸öµØ·½µÄ£¬ÆäËû²ãÐèÒªµÄʱºò¿ÉÒÔ·½±ãÌí¼Ó¡£
×ñÊØÒÀÀµ¹æÔò
µÚ¶þÌõ²»Ó¦¸Ã·ÅÆúµÄ¹æÔòÊÇÒÀÀµ¹æÔò£¬»òÕß˵ÊÇËüÃǵÄÒÀÀµ·½Ïò¡£ÍⲿµÄ·þÎñÐèÒªÊÊÅäÄÚ²¿£¬¶ø²»ÊÇ·´·½ÏòµÄ¡£
Èç¹ûÄã³¢ÊÔÖ±½ÓÈ¥µ÷ÓÃÒ»¸öÍⲿ API£¬Õâ¾ÍÊÇÓÐÎÊÌâµÄ£¬×îºÃÔÚ»¹Ã»³öÎÊÌâ֮ǰд¸öÊÊÅäÆ÷¡£
É̵êÓ¦ÓõÄÉè¼Æ
˵ÍêÁËÀíÂÛ£¬ÎÒÃǾͿÉÒÔ¿ªÊ¼Êµ¼ùÁË£¬ÏÂÃæÎÒÃÇÀ´Êµ¼ÊÉè¼ÆÒ»¸öÉ̵êÓ¦Óõġ£
É̵ê»á³öÊÛ²»Í¬ÖÖÀàµÄ±ý¸É£¬Óû§¿ÉÒÔ×Ô¼ºÑ¡ÔñÒª¹ºÂòµÄ±ý¸É£¬²¢Í¨¹ýÈý·½Ö§¸¶·þÎñ½øÐи¶¿î¡£
Óû§¿ÉÒÔÔÚÊ×Ò³¿´µ½ËùÓбý¸É£¬µ«ÊÇÖ»ÓеǼºó²ÅÄܹºÂò£¬µã»÷µÇ¼°´Å¥¿ÉÒÔÌø×ªµ½µÇ¼ҳ¡£

µÇ¼³É¹¦ºó£¬Óû§¾Í¿ÉÒ԰ѱý¸É¼Ó½ø¹ºÎï³µÁË¡£

°Ñ±ý¸É¼Ó½ø¹ºÎï³µºó£¬Óû§¾Í¿ÉÒÔ¸¶¿îÁË¡£¸¶¿îºó£¬¹ºÎï³µ»áÇå¿Õ£¬²¢²úÉúÒ»¸öÐµĶ©µ¥¡£
Ê×ÏÈ£¬ÎÒÃÇÀ´¶ÔʵÌå¡¢ÓÃÀýºÍ¹¦ÄܽøÐж¨Ò壬²¢¶ÔËüÃǽøÐзֲ㡣
Éè¼ÆÁìÓò
³ÌÐòÉè¼ÆÖÐ×îÖØÒªµÄ¾ÍÊÇÁìÓòÉè¼Æ£¬ËüÃDZíʾÁËʵÌåµ½Êý¾ÝµÄת»»¡£
É̵êµÄÁìÓò¿ÉÄܰüÀ¨£º
ÿ¸öʵÌåµÄÊý¾ÝÀàÐÍ£ºÓû§¡¢±ý¸É¡¢¹ºÎï³µºÍ¶©µ¥£»
Èç¹ûÄãÊÇÓÃOOP£¨ÃæÏò¶ÔÏó˼Ï룩ʵÏֵģ¬ÄÇôҲҪÉè¼ÆÉú³ÉʵÌåµÄ¹¤³§ºÍÀࣻ
Êý¾Ýת»»µÄº¯Êý¡£
ÁìÓòÖеÄת»»·½·¨Ó¦¸ÃÖ»ÒÀÀµÓÚÁìÓòµÄ¹æÔò£¬¶ø²»ÒÀÀµÓÚÆäËûÈκζ«Î÷¡£±ÈÈç·½·¨Ó¦¸ÃÊÇÕâÑùµÄ£º
¼ÆËã×ܼ۵ķ½·¨
¼ì²âÓû§¿ÚζµÄ·½·¨
¼ì²âÉÌÆ·ÊÇ·ñÔÚ¹ºÎï³µµÄ·½·¨

Éè¼ÆÓ¦Óòã
Ó¦Óòã°üº¬ÓÃÀý£¬Ò»¸öÓðüº¬Ò»¸ö²ÎÓëÕß¡¢Ò»¸ö¶¯×÷ºÍÒ»¸ö½á¹û¡£
ÔÚÉ̵êÓ¦ÓÃÀÎÒÃÇ¿ÉÒÔÕâÑùÇø·Ö£º
Ò»¸ö²úÆ·¹ºÂò³¡¾°£»
Ö§¸¶£¬µ÷ÓõÚÈý·½Ö§¸¶ÏµÍ³£»
Óë²úÆ·ºÍ¶©µ¥µÄ½»»¥£º¸üС¢²éѯ£»
¸ù¾Ý½ÇÉ«·ÃÎʲ»Í¬Ò³Ãæ¡£
ÎÒÃÇÒ»°ã¶¼ÊÇÓÃÖ÷ÌâÁìÓòÀ´ÃèÊöÓÃÀý£¬±ÈÈç¡°¹ºÂò¡±°üÀ¨ÏÂÃæµÄ²½Öè:
´Ó¹ºÎï³µÖвéѯÉÌÆ·²¢´´½¨Ð¶©µ¥£»
´´½¨Ö§¸¶¶©µ¥£»
Ö§¸¶Ê§°Üʱ֪ͨÓû§£»
Ö§¸¶³É¹¦£¬Çå¿Õ¹ºÎï³µ£¬ÏÔʾ¶©µ¥¡£
ÓÃÀý·½·¨¾ÍÊÇÃèÊöÕâ¸ö³¡¾°µÄ´úÂë¡£
´ËÍ⣬ÔÚÓ¦ÓòãÖл¹Óж˿ڡªÓÃÓÚÓëÍâ½çͨÐŵĽӿڡ£

Éè¼ÆÊÊÅäÆ÷²ã
ÔÚÊÊÅäÆ÷²ã£¬ÎÒÃÇΪÍⲿ·þÎñÉùÃ÷ÊÊÅäÆ÷¡£ÊÊÅäÆ÷¿ÉÒÔΪÎÒÃǵÄϵͳ¼æÈݸ÷ÖÖ²»¼æÈݵÄÍⲿ·þÎñ¡£
ÔÚǰ¶Ë£¬ÊÊÅäÆ÷Ò»°ãÊÇUI¿ò¼ÜºÍ¶Ôºó¶ËµÄAPIÇëÇóÄ£¿é¡£±ÈÈçÔÚÎÒÃǵÄÉ̵ê³ÌÐòÖлáÓõ½£º
Óû§½çÃæ£»
APIÇëÇóÄ£¿é£»
±¾µØ´æ´¢µÄÊÊÅäÆ÷£»
API·µ»Øµ½Ó¦ÓòãµÄÊÊÅäÆ÷¡£

¶Ô±È MVC ¼Ü¹¹
ÓÐʱÎÒÃǺÜÄÑÅжÏijЩÊý¾ÝÊôÓÚÄÄÒ»²ã£¬ÕâÀï¿ÉÒÔºÍ MVC ¼Ü¹¹×ö¸öС¶Ô±È£º
Model Ò»°ã¶¼ÊÇÁìÓòʵÌå
Controller Ò»°ãÊÇÓëת»»»òÕßÓ¦Óòã
View ÊÇÇý¶¯ÊÊÅäÆ÷
ÕâЩ¸ÅÄîËäÈ»ÔÚϸ½ÚÉϲ»Ì«Ïàͬ£¬µ«ÊǷdz£ÏàËÆ¡£
ʵÏÖϸ½Ú¡ªÁìÓò
Ò»µ©ÎÒÃÇÈ·¶¨ÁËÎÒÃÇÐèÒªÄÄЩʵÌ壬ÎÒÃǾͿÉÒÔ¿ªÊ¼¶¨ÒåËüÃǵÄÐÐΪÁË£¬ÏÂÃæ¾ÍÊÇÎÒÃÇÏîÄ¿µÄĿ¼½á¹¹£º
src/
|_domain/
|_user.ts
|_product.ts
|_order.ts
|_cart.ts
|_application/
|_addToCart.ts
|_authenticate.ts
|_orderProducts.ts
|_ports.ts
|_services/
|_authAdapter.ts
|_notificationAdapter.ts
|_paymentAdapter.ts
|_storageAdapter.ts
|_api.ts
|_store.tsx
|_lib/
|_ui/
|
ÁìÓò¶¼¶¨ÒåÔÚ domain Ŀ¼Ï£¬Ó¦Óò㶨ÒåÔÚ application Ŀ¼Ï£¬ÊÊÅäÆ÷¶¼¶¨ÒåÔÚ service
Ŀ¼Ï¡£×îºóÎÒÃÇ»¹»áÌÖÂÛĿ¼½á¹¹ÊÇ·ñ»áÓÐÆäËûµÄÌæ´ú·½°¸¡£
´´½¨ÁìÓòʵÌå
ÎÒÃÇÔÚÁìÓòÖÐÓÐ 4 ¸öʵÌ壺
product£¨²úÆ·£©
user£¨Óû§£©
order£¨¶©µ¥£©
cart£¨¹ºÎï³µ£©
ÆäÖÐ×îÖØÒªµÄ¾ÍÊÇ user£¬Ôڻػ°ÖУ¬ÎÒÃÇ»á°ÑÓû§ÐÅÏ¢´æÆðÀ´£¬ËùÒÔÎÒÃǵ¥¶ÀÔÚÁìÓòÖÐÉè¼ÆÒ»¸öÓû§ÀàÐÍ£¬Óû§ÀàÐͰüÀ¨ÒÔÏÂÊý¾Ý£º
// domain/user.ts
export type UserName = string;
export type User = {
id: UniqueId;
name: UserName;
email: Email;
preferences: Ingredient[];
allergies: Ingredient[];
};
|
Óû§¿ÉÒ԰ѱý¸É·Å½ø¹ºÎï³µ£¬ÎÒÃÇÒ²¸ø¹ºÎï³µºÍ±ý¸É¼ÓÉÏÀàÐÍ¡£
// domain/product.ts
export type ProductTitle = string;
export type Product = {
id: UniqueId;
title: ProductTitle;
price: PriceCents;
toppings: Ingredient[];
};
// domain/cart.ts
import { Product } from "./product";
export type Cart = {
products: Product[];
};
|
¸¶¿î³É¹¦ºó£¬½«´´½¨Ò»¸öж©µ¥£¬ÎÒÃÇÔÙÀ´Ìí¼ÓÒ»¸ö¶©µ¥ÊµÌåÀàÐÍ¡£
// domain/order.ts
¡ª ConardLi
export type OrderStatus = "new" | "delivery"
| "completed";
export type Order = {
user: UniqueId;
cart: Cart;
created: DateTimeString;
status: OrderStatus;
total: PriceCents;
};
|
Àí½âʵÌåÖ®¼äµÄ¹ØÏµ
ÒÔÕâÖÖ·½Ê½Éè¼ÆÊµÌåÀàÐ͵ĺô¦ÊÇÎÒÃÇ¿ÉÒÔ¼ì²éËüÃǵĹØÏµÍ¼ÊÇ·ñºÍ·ûºÏʵ¼ÊÇé¿ö£º

ÎÒÃÇ¿ÉÒÔ¼ì²éÒÔϼ¸µã£º
²ÎÓëÕßÊÇ·ñÊÇÒ»¸öÓû§
¶©µ¥ÀïÊÇ·ñÓÐ×ã¹»µÄÐÅÏ¢
ÓÐЩʵÌåÊÇ·ñÐèÒªÀ©Õ¹
ÔÚδÀ´ÊÇ·ñÓÐ×ã¹»µÄ¿ÉÀ©Õ¹ÐÔ
´ËÍ⣬ÔÚÕâ¸ö½×¶Î£¬ÀàÐÍ¿ÉÒÔ°ïÖúʶ±ðʵÌåÖ®¼äµÄ¼æÈÝÐԺ͵÷Ó÷½ÏòµÄ´íÎó¡£
Èç¹ûÒ»Çж¼·ûºÏÎÒÃÇÔ¤ÆÚµÄ£¬ÎÒÃǾͿÉÒÔ¿ªÊ¼Éè¼ÆÁìÓòת»»ÁË¡£
´´½¨Êý¾Ýת»»
ÎÒÃǸոÕÉè¼ÆµÄÕâЩÀàÐÍÊý¾Ý»á·¢Éú¸÷ÖÖ¸÷ÑùµÄÊÂÇé¡£ÎÒÃÇ¿ÉÒÔÌí¼ÓÉÌÆ·µ½¹ºÎï³µ¡¢Çå¿Õ¹ºÎï³µ¡¢¸üÐÂÉÌÆ·ºÍÓû§ÃûµÈ¡£ÏÂÃæÎÒÃÇ·Ö±ðÀ´ÎªÕâЩÊý¾Ýת»»´´½¨¶ÔÓ¦µÄº¯Êý£º
±ÈÈ磬ΪÁËÅжÏij¸öÓû§ÊÇϲ»¶»¹ÊÇÑá¶ñij¸ö¿Ú棬ÎÒÃÇ¿ÉÒÔ´´½¨Á½¸öº¯Êý£º
// domain/user.ts
export function hasAllergy(user: User, ingredient:
Ingredient): boolean {
return user.allergies.includes(ingredient);
}
export function hasPreference(user: User, ingredient:
Ingredient): boolean {
return user.preferences.includes(ingredient);
}
|
½«ÉÌÆ·Ìí¼Óµ½¹ºÎï³µ²¢¼ì²éÉÌÆ·ÊÇ·ñÔÚ¹ºÎï³µÖУº
// domain/cart.ts
¡ª ConardLi
export function addProduct(cart: Cart, product:
Product): Cart {
return { ...cart, products: [...cart.products,
product] };
}
export function contains(cart: Cart, product:
Product): boolean {
return cart.products.some(({ id }) => id ===
product.id);
}
|
ÏÂÃæÊǼÆËã×ܼۣ¨Èç¹ûÐèÒªµÄ»°ÎÒÃÇ»¹¿ÉÒÔÉè¼Æ¸ü¶àµÄ¹¦ÄÜ£¬±ÈÈçÅä´òÕÛ¡¢ÓÅ»ÝȯµÈ³¡¾°£©£º
// domain/product.ts
export function totalPrice(products: Product[]):
PriceCents {
return products.reduce((total, { price }) =>
total + price, 0);
}
|
´´½¨Ð¶©µ¥£¬²¢ºÍ¶ÔÓ¦Óû§ÒÔ¼°ËûµÄ¹ºÎï³µ½¨Á¢¹ØÁª¡£
// domain/order.ts
export function createOrder(user: User, cart:
Cart): Order {
return {
user: user.id,
cart,
created: new Date().toISOString(),
status: "new",
total: totalPrice(products),
};
}
|
ÏêϸÉè¼Æ¡ª¹²ÏíÄÚºË
Äã¿ÉÄÜÒѾעÒâµ½ÎÒÃÇÔÚÃèÊöÁìÓòÀàÐ͵ÄʱºòʹÓõÄһЩÀàÐÍ¡£ÀýÈç Email£¬UniqueId »ò DateTimeString
¡£ÕâЩÆäʵ¶¼ÊÇÀàÐͱðÃû£º
// shared-kernel.d.ts
type Email = string;
type UniqueId = string;
type DateTimeString = string;
type PriceCents = number;
|
ÎÒÓà DateTimeString ´úÌæ string À´¸üÇåÎúµÄ±íÃ÷Õâ¸ö×Ö·û´®ÊÇÓÃÀ´×öʲôµÄ¡£ÕâЩÀàÐÍÔ½Ìù½üʵ¼Ê£¬¾Í¸üÈÝÒ×ÅŲéÎÊÌâ¡£
ÕâЩÀàÐͶ¼¶¨ÒåÔÚ shared-kernel.d.ts ÎļþÀï¡£¹²ÏíÄÚºËÖ¸µÄÊÇһЩ´úÂëºÍÊý¾Ý£¬¶ÔËûÃǵÄÒÀÀµ²»»áÔö¼ÓÄ£¿éÖ®¼äµÄñîºÏ¶È¡£
ÔÚʵ¼ùÖУ¬¹²ÏíÄں˿ÉÒÔÕâÑù½âÊÍ£ºÎÒÃÇÓõ½ TypeScript£¬Ê¹ÓÃËüµÄ±ê×¼ÀàÐͿ⣬µ«ÎÒÃDz»»á°ÑËüÃÇ¿´×÷ÊÇÒ»¸öÒÀÀµÏî¡£ÕâÊÇÒòΪʹÓÃËüÃǵÄÄ£¿é»¥Ï಻»á²úÉúÓ°Ïì²¢ÇÒ¿ÉÒÔ±£³Ö½âñî¡£
²¢²»ÊÇËùÓдúÂë¶¼¿ÉÒÔ±»¿´×÷Êǹ²ÏíÄںˣ¬×îÖ÷ÒªµÄÔÔòÊÇÕâÑùµÄ´úÂë±ØÐëºÍϵͳ´¦´¦¶¼ÊǼæÈݵġ£Èç¹û³ÌÐòµÄÒ»²¿·ÖÊÇÓÃ
TypeScript ±àдµÄ£¬¶øÁíÒ»²¿·ÖÊÇÓÃÁíÒ»ÖÖÓïÑÔ±àдµÄ£¬¹²ÏíºËÐÄÖ»¿ÉÒÔ°üº¬Á½ÖÖÓïÑÔ¶¼¿ÉÒÔ¹¤×÷µÄ²¿·Ö¡£
ÔÚÎÒÃǵÄÀý×ÓÖУ¬Õû¸öÓ¦ÓóÌÐò¶¼ÊÇÓà TypeScript ±àдµÄ£¬ËùÒÔÄÚÖÃÀàÐ͵ıðÃûÍêÈ«¿ÉÒÔµ±×ö¹²ÏíÄں˵ÄÒ»²¿·Ö¡£ÕâÖÖÈ«¾Ö¶¼¿ÉÓõÄÀàÐͲ»»áÔö¼ÓÄ£¿éÖ®¼äµÄñîºÏ£¬²¢ÇÒÔÚ³ÌÐòµÄÈκβ¿·Ö¶¼¿ÉÒÔʹÓõ½¡£
ʵÏÖϸ½Ú¡ªÓ¦Óòã
ÎÒÃÇÒѾÍê³ÉÁËÁìÓòµÄÉè¼Æ£¬ÏÂÃæ¿ÉÒÔÉè¼ÆÓ¦ÓòãÁË¡£
ÕâÒ»²ã»á°üº¬¾ßÌåµÄÓÃÀýÉè¼Æ£¬±ÈÈçÒ»¸öÓÃÀýÊǽ«ÉÌÆ·Ìí¼Óµ½¹ºÎï³µ²¢Ö§¸¶µÄÍêÕû¹ý³Ì¡£
ÓÃÀý»áÉæ¼°Ó¦ÓúÍÍⲿ·þÎñµÄ½»»¥£¬ÓëÍⲿ·þÎñµÄ½»»¥¶¼ÊǸ±×÷Óá£ÎÒÃǶ¼ÖªµÀµ÷ÓûòÕßµ÷ÊÔûÓи±×÷Óõķ½·¨»á¸ü¼òµ¥Ò»Ð©£¬ËùÒԴ󲿷ÖÁìÓòº¯Êý¶¼ÊµÏÖΪ³É´¿º¯ÊýÁË¡£
ΪÁ˽«ÎÞ¸±×÷ÓõĴ¿º¯ÊýºÍÓëÓи±×÷ÓõĽ»»¥½áºÏÆðÀ´£¬ÎÒÃÇ¿ÉÒÔ½«Ó¦ÓòãÓÃ×÷Óи±×÷ÓõķǴ¿ÉÏÏÂÎÄ¡£
·Ç´¿ÉÏÏÂÎÄ´¿Êý¾Ýת»»
Ò»¸ö°üº¬¸±×÷ÓõķǴ¿ÉÏÏÂÎĺʹ¿Êý¾Ýת»»ÊÇÕâÑùÒ»ÖÖ´úÂë×éÖ¯·½Ê½£º
Ê×ÏÈÖ´ÐÐÒ»¸ö¸±×÷ÓÃÀ´»ñȡһЩÊý¾Ý£»
È»ºó¶ÔÊý¾ÝÖ´Ðд¿º¯Êý½øÐÐÊý¾Ý´¦Àí£»
×îºóÔÙÖ´ÐÐÒ»¸ö¸±×÷Ó㬴洢»ò´«µÝÕâ¸ö½á¹û¡£
±ÈÈ磬¡°½«ÉÌÆ··ÅÈ빺Îï³µ¡±Õâ¸öÓÃÀý£º
Ê×ÏÈ£¬´ÓÊý¾Ý¿âÀï»ñÈ¡¹ºÎï³µµÄ״̬£»
È»ºóµ÷ÓùºÎï³µ¸üк¯Êý£¬°ÑÒªÌí¼ÓµÄÉÌÆ·ÐÅÏ¢´«½øÈ¥£»
×îºó½«¸üÐµĹºÎï³µ±£´æµ½Êý¾Ý¿âÖС£
Õâ¸ö¹ý³Ì¾ÍÏñÒ»¸ö¡°ÈýÃ÷ÖΡ±£º¸±×÷Óᢴ¿º¯Êý¡¢¸±×÷Óá£ËùÓÐÖ÷ÒªµÄÂß¼´¦Àí¶¼ÔÚµ÷Óô¿º¯Êý½øÐÐÊý¾Ýת»»ÉÏ£¬ËùÓÐÓëÍⲿµÄͨÐŶ¼¸ôÀëÔÚÒ»¸öÃüÁîʽµÄÍâ¿ÇÖС£

Éè¼ÆÓÃÀý
ÎÒÃÇÑ¡Ôñ½áÕËÕâ¸ö³¡¾°À´×öÓÃÀýÉè¼Æ£¬Ëü¸ü¾ß´ú±íÐÔ£¬ÒòΪËüÊÇÒì²½µÄ£¬¶øÇÒ»áÓëºÜ¶àµÚÈý·½·þÎñ½øÐн»»¥¡£
ÎÒÃÇ¿ÉÒÔÏëÒ»Ï룬ͨ¹ýÕû¸öÓÃÀýÎÒÃÇÒª±í´ïʲô¡£Óû§µÄ¹ºÎï³µÀïÓÐһЩ±ý¸É£¬µ±Óû§µã»÷¹ºÂò°´Å¥µÄʱºò£º
Òª´´½¨Ò»¸öж©µ¥£»
ÔÚµÚÈý·½Ö§¸¶ÏµÍ³ÖÐÖ§¸¶£»
Èç¹ûÖ§¸¶Ê§°Ü£¬Í¨ÖªÓû§£»
Èç¹ûÖ§¸¶³É¹¦£¬½«¶©µ¥±£´æÔÚ·þÎñÆ÷ÉÏ£»
ÔÚ±¾µØ´æ´¢±£´æ¶©µ¥Êý¾Ý£¬²¢ÔÚÒ³ÃæÉÏÏÔʾ£»
Éè¼Æº¯ÊýµÄʱºò£¬ÎÒÃÇ»á°ÑÓû§ºÍ¹ºÎï³µ¶¼×÷Ϊ²ÎÊý£¬È»ºóÈÃÕâ¸ö·½·¨Íê³ÉÕû¸ö¹ý³Ì¡£
type OrderProducts
= (user: User, cart: Cart) => Promise<void>;
|
µ±È»£¬ÀíÏëÇé¿öÏ£¬ÓÃÀý²»Ó¦¸Ã½ÓÊÕÁ½¸öµ¥¶ÀµÄ²ÎÊý£¬¶øÊǽÓÊÕÒ»¸ö·â×°ºóµÄ¶ÔÏó£¬ÎªÁ˾«¼ò´úÂ룬ÎÒÃÇÏÈÕâÑù´¦Àí¡£
±àдӦÓòãµÄ½Ó¿Ú
ÎÒÃÇÔÙÀ´×Ðϸ¿´¿´ÓÃÀýµÄ²½Ö裺¶©µ¥´´½¨±¾Éí¾ÍÊÇÒ»¸öÁìÓòº¯Êý£¬ÆäËûÒ»ÇвÙ×÷ÎÒÃǶ¼Òªµ÷ÓÃÍⲿ·þÎñ¡£
ÎÒÃÇÒªÀμǣ¬Íⲿ·½·¨ÓÀÔ¶ÒªÊÊÅäÎÒÃǵÄÐèÇó¡£ËùÒÔ£¬ÔÚÓ¦Óò㣬ÎÒÃDz»½öÒªÃèÊöÓÃÀý±¾Éí£¬Ò²Òª¶¨Òåµ÷ÓÃÍⲿ·þÎñµÄͨÐÅ·½Ê½¡ª¶Ë¿Ú¡£
ÏëÒ»ÏëÎÒÃÇ¿ÉÄÜ»áÓõ½µÄ·þÎñ£º
µÚÈý·½Ö§¸¶·þÎñ£»
֪ͨÓû§Ê¼þºÍ´íÎóµÄ·þÎñ£»
½«Êý¾Ý±£´æµ½±¾µØ´æ´¢µÄ·þÎñ¡£

×¢Ò⣬ÎÒÃÇÏÖÔÚÌÖÂÛµÄÊÇÕâЩ·þÎñµÄ interface £¬¶ø²»ÊÇËüÃǵľßÌåʵÏÖ¡£ÔÚÕâ¸ö½×¶Î£¬ÃèÊö±ØÒªµÄÐÐΪ¶ÔÎÒÃÇÀ´ËµºÜÖØÒª£¬ÒòΪÕâÊÇÎÒÃÇÔÚÃèÊö³¡¾°Ê±ÔÚÓ¦ÓòãËùÒÀÀµµÄÐÐΪ¡£
ÈçºÎʵÏÖÏÖÔÚ²»ÊÇÖØµã£¬ÎÒÃÇ¿ÉÒÔÔÚ×îºóÔÙ¿¼Âǵ÷ÓÃÄÄЩÍⲿ·þÎñ£¬ÕâÑù´úÂë²ÅÄܾ¡Á¿±£Ö¤µÍñîºÏ¡£
ÁíÍ⻹ҪעÒ⣬ÎÒÃǰ´¹¦Äܲð·Ö½Ó¿Ú¡£ÓëÖ§¸¶Ïà¹ØµÄÒ»Çж¼ÔÚͬһ¸öÄ£¿éÖУ¬Óë´æ´¢Ïà¹ØµÄ¶¼ÔÚÁíÒ»¸öÄ£¿éÖС£ÕâÑù¸üÈÝÒ×È·±£²»µÄͬµÚÈý·½·þÎñµÄ¹¦Äܲ»»á»ìÔÚÒ»Æð¡£
Ö§¸¶ÏµÍ³½Ó¿Ú
ÎÒÃÇÕâ¸öÉ̵êÓ¦ÓÃÖ»ÊǸöС Demo£¬ËùÒÔÖ§¸¶ÏµÍ³»áºÜ¼òµ¥¡£Ëü»áÓÐÒ»¸ö tryPay ·½·¨£¬Õâ¸ö·½·¨½«½ÓÊÜÐèÒªÖ§¸¶µÄ½ð¶î£¬È»ºó·µ»ØÒ»¸ö²¼¶ûÖµÀ´±íÃ÷Ö§¸¶µÄ½á¹û¡£
// application/ports.ts
¡ª ConardLi
export interface PaymentService {
tryPay(amount: PriceCents): Promise<boolean>;
}
|
Ò»°ãÀ´Ëµ£¬¸¶¿îµÄ´¦ÀíÊÇÔÚ·þÎñ¶Ë¡£µ«ÎÒÃÇÖ»ÊǼòµ¥ÑÝʾһÏ£¬ËùÒÔÔÚǰ¶Ë¾ÍÖ±½Ó´¦ÀíÁË¡£ºóÃæÎÒÃÇÒ²»áµ÷ÓÃһЩ¼òµ¥µÄAPI£¬¶ø²»ÊÇÖ±½ÓºÍÖ§¸¶ÏµÍ³½øÐÐͨÐÅ¡£
֪ͨ·þÎñ½Ó¿Ú
Èç¹û³öÏÖһЩÎÊÌ⣬ÎÒÃDZØÐë֪ͨµ½Óû§¡£
ÎÒÃÇ¿ÉÒÔÓø÷ÖÖ²»Í¬µÄ·½Ê½Í¨ÖªÓû§¡£±ÈÈçʹÓà UI£¬·¢ËÍÓʼþ£¬ÉõÖÁ¿ÉÒÔÈÃÓû§µÄÊÖ»úÕñ¶¯¡£
Ò»°ãÀ´Ëµ£¬Í¨Öª·þÎñ×îºÃÒ²³éÏó³öÀ´£¬ÕâÑùÎÒÃÇÏÖÔھͲ»Óÿ¼ÂÇʵÏÖÁË¡£
¸øÓû§·¢ËÍÒ»Ìõ֪ͨ£º
// application/ports.ts
export interface NotificationService {
notify(message: string): void;
}
|
±¾µØ´æ´¢½Ó¿Ú
ÎÒÃǻὫÐµĶ©µ¥±£´æÔÚ±¾µØµÄ´æ´¢¿âÖС£
Õâ¸ö´æ´¢¿ÉÒÔÊÇÈκζ«Î÷£ºRedux¡¢MobX¡¢Èκδ洢¶¼¿ÉÒÔ¡£´æ´¢¿â¿ÉÒÔÔÚ²»Í¬ÊµÌåÉϽøÐвð·Ö£¬Ò²¿ÉÒÔÊÇÕû¸öÓ¦ÓóÌÐòµÄÊý¾Ý¶¼Î¬»¤ÔÚÒ»Æð¡£²»¹ýÏÖÔÚ¶¼²»ÖØÒª£¬ÒòΪÕâЩ¶¼ÊÇʵÏÖϸ½Ú¡£
ÎÒϰ¹ßµÄ×ö·¨ÊÇΪÿ¸öʵÌå¶¼´´½¨Ò»¸öµ¥¶ÀµÄ´æ´¢½Ó¿Ú£ºÒ»¸öµ¥¶ÀµÄ½Ó¿Ú´æ´¢Óû§Êý¾Ý£¬Ò»¸ö´æ´¢¹ºÎï³µ£¬Ò»¸ö´æ´¢¶©µ¥£º
// application/ports.ts
¡ª ConardLi
export interface OrdersStorageService {
orders: Order[];
updateOrders(orders: Order[]): void;
}
|
ÓÃÀý·½·¨
ÏÂÃæÎÒÃÇÀ´¿´¿´Äܲ»ÄÜÓÃÏÖÓеÄÁìÓò·½·¨ºÍ¸Õ¸Õ½¨µÄ½Ó¿ÚÀ´¹¹½¨Ò»¸öÓÃÀý¡£½Å±¾½«°üº¬Èçϲ½Ö裺
ÑéÖ¤Êý¾Ý£»
´´½¨¶©µ¥£»
Ö§¸¶¶©µ¥£»
֪ͨÎÊÌ⣻
±£´æ½á¹û¡£

Ê×ÏÈ£¬ÎÒÃÇÉùÃ÷³öÀ´ÎÒÃÇÒªµ÷ÓõķþÎñµÄÄ£¿é¡£TypeScript »áÌáʾÎÒÃÇûÓиø³ö½Ó¿ÚµÄʵÏÖ£¬ÏȲ»Òª¹ÜËû¡£
// application/orderProducts.ts
¡ª ConardLi
const payment: PaymentService = {};
const notifier: NotificationService = {};
const orderStorage: OrdersStorageService = {};
|
ÏÖÔÚÎÒÃÇ¿ÉÒÔÏñʹÓÃÕæÕýµÄ·þÎñÒ»ÑùʹÓÃÕâЩģ¿é¡£ÎÒÃÇ¿ÉÒÔ·ÃÎÊËûÃǵÄ×ֶΣ¬µ÷ÓÃËûÃǵķ½·¨¡£ÕâÔÚ°ÑÓÃÀýת»»Îª´úÂëµÄʱºò·Ç³£ÓÐÓá£
ÏÖÔÚ£¬ÎÒÃÇ´´½¨Ò»¸öÃûΪ orderProducts µÄ·½·¨À´´´½¨Ò»¸ö¶©µ¥£º
// application/orderProducts.ts
¡ª ConardLi
//...
async function orderProducts(user: User, cart:
Cart) {
const order = createOrder(user, cart);
}
|
ÕâÀÎÒÃǰѽӿڵ±×÷ÊÇÐÐΪµÄÔ¼¶¨¡£Ò²¾ÍÊÇ˵ÒÔÄ£¿éʾÀý»áÕæÕýÖ´ÐÐÎÒÃÇÆÚÍûµÄ²Ù×÷£º
// application/orderProducts.ts
¡ª ConardLi
//...
async function orderProducts(user: User, cart:
Cart) {
const order = createOrder(user, cart);
// Try to pay for the order;
// Notify the user if something is wrong:
const paid = await payment.tryPay(order.total);
if (!paid) return notifier.notify("Oops!
??");
// Save the result and clear the cart:
const { orders } = orderStorage;
orderStorage.updateOrders([...orders, order]);
cartStorage.emptyCart();
}
|
×¢Ò⣬ÓÃÀý²»»áÖ±½Óµ÷ÓõÚÈý·½·þÎñ¡£ËüÒÀÀµÓÚ½Ó¿ÚÖÐÃèÊöµÄÐÐΪ£¬ËùÒÔÖ»Òª½Ó¿Ú±£³Ö²»±ä£¬ÎÒÃǾͲ»ÐèÒª¹ØÐÄÄĸöÄ£¿éÀ´ÊµÏÖËüÒÔ¼°ÈçºÎʵÏÖËü£¬ÕâÑùµÄÄ£¿é¾ÍÊÇ¿ÉÌæ»»µÄ¡£
ʵÏÖϸ½Ú¡ªÊÊÅäÆ÷²ã
ÎÒÃÇÒѾ°ÑÓÃÀý¡°·Ò롱³É TypeScript ÁË£¬ÏÖÔÚÎÒÃÇÀ´¼ì²éÒ»ÏÂÏÖʵÊÇ·ñ·ûºÏÎÒÃǵÄÐèÇó¡£
ͨ³£Çé¿öÏÂÊDz»»áµÄ£¬ËùÒÔÎÒÃÇҪͨ¹ý·â×°ÊÊÅäÆ÷À´µ÷ÓõÚÈý·½·þÎñ¡£
Ìí¼ÓUIºÍÓÃÀý
Ê×ÏÈ£¬µÚÒ»¸öÊÊÅäÆ÷¾ÍÊÇÒ»¸ö UI ¿ò¼Ü¡£Ëü°Ñä¯ÀÀÆ÷µÄ API ÓëÎÒÃǵÄÓ¦ÓóÌÐòÁ¬½ÓÆðÀ´¡£ÔÚ¶©µ¥´´½¨µÄÕâ¸ö³¡¾°£¬¾ÍÊÇ¡°½áÕÊ¡±°´Å¥ºÍµã»÷ʼþµÄ´¦Àí·½·¨£¬ÕâÀï»áµ÷ÓþßÌåÓÃÀýµÄ¹¦ÄÜ¡£
// ui/components/Buy.tsx
¡ª ConardLi
export function Buy() {
// Get access to the use case in the component:
const { orderProducts } = useOrderProducts();
async function handleSubmit(e: React.FormEvent)
{
setLoading(true);
e.preventDefault();
// Call the use case function:
await orderProducts(user!, cart);
setLoading(false);
}
return ( <section> <h2>Checkout</h2>
<form onSubmit={handleSubmit}>{/* ... */}</form>
</section>
);
}
|
ÎÒÃÇ¿ÉÒÔͨ¹ýÒ»¸ö Hook À´·â×°ÓÃÀý£¬½¨Òé°ÑËùÓеķþÎñ¶¼·â×°µ½ÀïÃæ£¬×îºó·µ»ØÓÃÀýµÄ·½·¨£º
// application/orderProducts.ts
¡ª ConardLi
export function useOrderProducts() {
const notifier = useNotifier();
const payment = usePayment();
const orderStorage = useOrdersStorage();
async function orderProducts(user: User, cookies:
Cookie[]) {
// ¡
}
return { orderProducts };
}
|
ÎÒÃÇʹÓà hook À´×÷Ϊһ¸öÒÀÀµ×¢Èë¡£Ê×ÏÈÎÒÃÇʹÓà useNotifier£¬usePayment£¬useOrdersStorage
Õ⼸¸ö hook À´»ñÈ¡·þÎñµÄʵÀý£¬È»ºóÎÒÃÇÓú¯Êý useOrderProducts ´´½¨Ò»¸ö±Õ°ü£¬ÈÃËûÃÇ¿ÉÒÔÔÚ
orderProducts º¯ÊýÖб»µ÷Óá£
ÁíÍâÐèҪעÒâµÄÊÇ£¬ÓÃÀýº¯ÊýºÍÆäËûµÄ´úÂëÊÇ·ÖÀëµÄ£¬ÕâÑù¶Ô²âÊÔ¸ü¼ÓÓѺá£
Ö§¸¶·þÎñʵÏÖ
ÓÃÀýʹÓà PaymentService ½Ó¿Ú£¬ÎÒÃÇÏÈÀ´ÊµÏÖһϡ£
¶ÔÓÚ¸¶¿î²Ù×÷£¬ÎÒÃÇÒÀȻʹÓÃÒ»¸ö¼ÙµÄ API ¡£Í¬ÑùµÄ£¬ÎÒÃÇÏÖÔÚ»¹ÊÇû±ØÒª±àдȫ²¿µÄ·þÎñ£¬ÎÒÃÇ¿ÉÒÔÖ®ºóÔÙʵÏÖ£¬ÏÖÔÚ×îÖØÒªµÄÊÇʵÏÖÖ¸¶¨µÄÐÐΪ£º
// services/paymentAdapter.ts
¡ª ConardLi
import { fakeApi } from "./api";
import { PaymentService } from "../application/ports";
export function usePayment(): PaymentService {
return {
tryPay(amount: PriceCents) {
return fakeApi(true);
},
};
}
|
fakeApi Õâ¸öº¯Êý»áÔÚ 450 ºÁÃëºó´¥·¢µÄ³¬Ê±£¬Ä£ÄâÀ´×Ô·þÎñÆ÷µÄÑÓ³ÙÏìÓ¦£¬Ëü·µ»ØÎÒÃÇ´«ÈëµÄ²ÎÊý¡£
// services/api.ts
¡ª ConardLi
export function fakeApi<TResponse>(response:
TResponse): Promise<TResponse> {
return new Promise((res) => setTimeout(() =>
res(response), 450));
}
|
֪ͨ·þÎñʵÏÖ
ÎÒÃǾͼòµ¥Ê¹Óà alert À´ÊµÏÖ֪ͨ£¬ÒòΪ´úÂëÊǽâñîµÄ£¬ÒÔºóÔÙÀ´ÖØÐ´Õâ¸ö·þÎñÒ²²»³ÉÎÊÌâ¡£
// services/notificationAdapter.ts
¡ª ConardLi
import { NotificationService } from "../application/ports";
export function useNotifier(): NotificationService
{
return {
notify: (message: string) => window.alert(message),
};
}
|
±¾µØ´æ´¢ÊµÏÖ
ÎÒÃǾÍͨ¹ý React.Context ºÍ Hooks À´ÊµÏÖ±¾µØ´æ´¢¡£
ÎÒÃÇ´´½¨Ò»¸öÐ嵀 context£¬È»ºó°ÑËü´«¸ø provider£¬È»ºóµ¼³öÈÃÆäËûµÄÄ£¿é¿ÉÒÔͨ¹ý Hooks
ʹÓá£
// store.tsx
¡ª ConardLi
const StoreContext = React.createContext<any>({});
export const useStore = () => useContext(StoreContext);
export const Provider: React.FC = ({ children
}) => {
// ...Other entities...
const [orders, setOrders] = useState([]);
const value = {
// ...
orders,
updateOrders: setOrders,
};
return ( <StoreContext.Provider value={value}>{children}</StoreContext.Provider>
);
};
|
ÎÒÃÇ¿ÉÒÔ¸øÃ¿Ò»¸ö¹¦Äܵ㶼ʵÏÖÒ»¸ö Hook ¡£ÕâÑùÎÒÃǾͲ»»áÆÆ»µ·þÎñ½Ó¿ÚºÍ´æ´¢£¬ÖÁÉÙÔڽӿڵĽǶÈÀ´ËµËûÃÇÊÇ·ÖÀëµÄ¡£
// services/storageAdapter.ts
export function useOrdersStorage(): OrdersStorageService
{
return useStore();
}
|
´ËÍ⣬ÕâÖÖ·½·¨»¹¿ÉÒÔʹÎÒÃÇÄܹ»ÎªÃ¿¸öÉÌµê¶¨ÖÆ¶îÍâµÄÓÅ»¯£º´´½¨Ñ¡ÔñÆ÷¡¢»º´æµÈ¡£
ÑéÖ¤Êý¾ÝÁ÷³Ìͼ
ÏÖÔÚÈÃÎÒÃÇÑéÖ¤Ò»ÏÂÓû§ÊÇÔõôºÍÓ¦ÓóÌÐòͨÐŵġ£

Óû§Óë UI ²ã½»»¥£¬µ«ÊÇ UI Ö»ÄÜͨ¹ý¶Ë¿Ú·ÃÎÊ·þÎñ½Ó¿Ú¡£Ò²¾ÍÊÇ˵£¬ÎÒÃÇ¿ÉÒÔËæÊ±Ìæ»» UI¡£
ÓÃÀýÊÇÔÚÓ¦Óò㴦ÀíµÄ£¬Ëü¿ÉÒÔ׼ȷµØ¸æËßÎÒÃÇÐèÒªÄÄЩÍⲿ·þÎñ¡£ËùÓÐÖ÷ÒªµÄÂß¼ºÍÊý¾Ý¶¼·â×°ÔÚÁìÓòÖС£
ËùÓÐÍⲿ·þÎñ¶¼Òþ²ØÔÚ»ù´¡ÉèÊ©ÖУ¬²¢ÇÒ×ñÊØÎÒÃǵĹ淶¡£Èç¹ûÎÒÃÇÐèÒª¸ü¸Ä·¢ËÍÏûÏ¢µÄ·þÎñ£¬Ö»ÐèÒªÐ޸ķ¢ËÍÏûÏ¢·þÎñµÄÊÊÅäÆ÷¡£
ÕâÑùµÄ·½°¸ÈôúÂë¸ü·½±ãÌæ»»¡¢¸üÈÝÒײâÊÔ¡¢À©Õ¹ÐÔ¸üÇ¿£¬ÒÔÊÊÓ¦²»¶Ï±ä»¯µÄÐèÇó¡£
ÓÐʲô¿ÉÒԸĽøµÄ
ÉÏÃæ½éÉܵÄÕâЩÒѾ¿ÉÒÔÈÃÄ㿪ʼ²¢³õ²½Á˽â¸É¾»µÄ¼Ü¹¹ÁË£¬µ«ÊÇÎÒÏëÖ¸³öÉÏÃæÎÒΪÁËÈÃʾÀý¸ü¼òµ¥×öµÄһЩ͵¹¤¼õÁϵÄÊÂÇé¡£
¶ÁÍêÏÂÃæµÄÄÚÈÝ£¬´ó¼Ò¿ÉÒÔÀí½â ¡°Ã»ÓÐ͵¹¤¼õÁÏ¡±µÄ¸É¾»¼Ü¹¹ÊÇʲôÑù×ӵġ£
ʹÓöÔÏó¶ø²»ÊÇÊý×ÖÀ´±íʾ¼Û¸ñ
Äã¿ÉÄÜÒѾעÒâµ½ÎÒÓÃÒ»¸öÊý×ÖÀ´ÃèÊö¼Û¸ñ£¬Õâ²»ÊÇÒ»¸öºÃϰ¹ß¡£
// shared-kernel.d.ts
type PriceCents = number;
|
Êý×ÖÖ»ÄܱíʾÊýÁ¿£¬²»Äܱíʾ»õ±Ò£¬Ã»Óлõ±ÒµÄ¼Û¸ñÊÇûÓÐÒâÒåµÄ¡£ÀíÏëÇé¿öÏ£¬¼Û¸ñÓ¦¸ÃÊǾßÓÐÁ½¸ö×ֶεĶÔÏ󣺼ÛÖµºÍ»õ±Ò¡£
type Currency
= "RUB" | "USD" | "EUR"
| "SEK";
type AmountCents = number;
type Price = {
value: AmountCents;
currency: Currency;
};
|
ÕâÑù¾ÍÄܽâ¾ö´æ´¢»õ±ÒµÄÎÊÌâÁË£¬²¢¿ÉÒÔʡȥ´óÁ¿µÄ´æ´¢ºÍ´¦Àí»õ±ÒµÄ¾«Á¦¡£ÔÚʾÀýÖÐÎÒûÓÐÕâô×öÊÇΪÁËÈÃÕâ¸öÀý×Ó¾¡Á¿¼òµ¥¡£ÔÚÕæÊµµÄÇé¿öÀ¼Û¸ñµÄ½á¹¹¶¨Òå»á¸ü¼Ó½Ó½üÉÏÃæµÄд·¨¡£
ÁíÍ⣬ֵµÃÒ»ÌáµÄÊǼ۸ñµÄµ¥Î»£¬±ÈÈçÃÀÔªµÄ×îСµ¥Î»ÊÇÃÀ·Ö¡£ÒÔÕâÖÖ·½Ê½ÏÔʾ¼Û¸ñÈÃÎÒ¿ÉÒÔ±ÜÃ⿼ÂǸ¡µãÊý¼ÆËãµÄÎÊÌâ¡£
°´¹¦Äܲð·Ö´úÂ룬¶ø²»Êǰ´²ã
´úÂë¿ÉÒÔ ¡°°´¹¦ÄÜ¡± ²ð·Öµ½Îļþ¼ÐÖУ¬¶ø²»ÊÇ¡°°´²ã¡±£¬Ò»¿é¹¦ÄܾÍÊÇÏÂÃæ±ýͼµÄÒ»²¿·Ö¡£
ÕâÖֽṹ¸üÇåÎú£¬ÒòΪËü¿ÉÒÔÈÃÄã·Ö±ð²¿Êð²»Í¬µÄ¹¦Äܵ㣺

×¢Òâ¿ç×é¼þʹÓÃ
Èç¹ûÎÒÃÇÕýÔÚÌÖÂÛ½«ÏµÍ³²ð·ÖΪ×é¼þ£¬¾Í²»µÃ²»¿¼ÂÇ¿ç×é¼þ´úÂëʹÓõÄÎÊÌâ¡£ÎÒÃÇÔÙÀ´¿´¿´´´½¨¶©µ¥µÄ´úÂ룺
import { Product,
totalPrice } from "./product";
export function createOrder(user: User, cart:
Cart): Order {
return {
user: user.id,
cart,
created: new Date().toISOString(),
status: "new",
total: totalPrice(products),
};
}
|
Õâ¸öº¯ÊýÓõ½ÁË´ÓÁíÒ»¸ö Product Ä£¿éÒýÈëµÄ totalPrice ·½·¨¡£ÕâÑùʹÓñ¾ÉíûÓÐʲôÎÊÌ⣬µ«ÊÇÈç¹ûÎÒÃÇÒª¿¼ÂǰѴúÂë²ð·Öµ½¶ÀÁ¢µÄ¹¦ÄܵÄʱºò£¬ÎÒÃDz»ÄÜÖ±½Ó·ÃÎÊÆäËûÄ£¿éµÄ´úÂë¡£
ʹÓà ts-brand £¬¶ø²»ÊÇÀàÐͱðÃû
ÔÚ¹²ÏíÄں˵ıàдÖУ¬ÎÒʹÓÃÁËÀàÐͱðÃû¡£ËüÃǺÜÈÝÒ×ʵÏÖ£¬µ«È±µãÊÇ TypeScript ûÓÐ¼à¿Ø²¢Ç¿ÖÆÖ´ÐÐËüÃǵĻúÖÆ¡£
Õâ¿´ÆðÀ´Ò²²»ÊǸöÎÊÌ⣺ÄãÊÇÓà string ÀàÐÍÈ¥Ìæ´ú DateTimeString Ò²²»»áÔõôÑù£¬´úÂ뻹ÊÇ»á±àÒë³É¹¦¡£µ«ÊÇ£¬ÕâÑù»áÈôúÂë±äµÃ´àÈõ¡¢¿É¶ÁÐÔÒ²ºÜ²î£¬ÒòΪÕâÑùÄã¿ÉÒÔÓÃÈÎÒâµÄ×Ö·û´®£¬µ¼Ö´íÎóµÄ¿ÉÄÜÐÔ»áÔö¼Ó¡£
ÓÐÒ»ÖÖ·½·¨¿ÉÒÔÈà TypeScript Àí½âÎÒÃÇÏëÒªÒ»¸öÌØ¶¨µÄÀàÐÍ ¡ª ts-brand£¨https://github.com/kourge/ts-brand£©¡£Ëü¿ÉÒÔ׼ȷµÄ¸ú×ÙÀàÐ͵ÄʹÓ÷½Ê½£¬µ«»áʹ´úÂë¸ü¸´ÔÓһЩ¡£
×¢ÒâÁìÓòÖпÉÄܵÄÒÀÀµ
½ÓÏÂÀ´µÄÎÊÌâÊÇÎÒÃÇÔÚ createOrder º¯ÊýµÄÁìÓòÖд´½¨ÁËÒ»¸öÈÕÆÚ£º
import { Product,
totalPrice } from "./product";
export function createOrder(user: User, cart:
Cart): Order {
return {
user: user.id,
cart,
// §£§à§ä §ï§ä§Ñ §ã§ä§â§à§Ü§Ñ:
created: new Date().toISOString(),
status: "new",
total: totalPrice(products),
};
}
|
new Date().toISOString() ÕâÑùµÄº¯Êý¿ÉÄÜ»á±»ÖØ¸´µ÷Óúܶà´Î£¬ÎÒÃÇ¿ÉÒÔ°ÑËü·â×°µ½Ò»¸ö
hleper ÀïÃæ£º
// lib/datetime.ts
¡ª ConardLi
export function currentDatetime(): DateTimeString
{
return new Date().toISOString();
}
|
È»ºóÔÚÁìÓòÖе÷ÓÃËü£º
// domain/order.ts
import { currentDatetime } from "../lib/datetime";
import { Product, totalPrice } from "./product";
export function createOrder(user: User, cart:
Cart): Order {
return {
user: user.id,
cart,
created: currentDatetime(),
status: "new",
total: totalPrice(products),
};
}
|
µ«ÊÇÁìÓòµÄÔÔòÊDz»ÄÜÒÀÀµÆäËûÈκζ«Î÷£¬ËùÒÔ createOrder º¯Êý×îºÃÊÇËùÓÐÊý¾Ý¶¼´ÓÍâÃæ´«½øÀ´£¬ÈÕÆÚ¿ÉÒÔ×÷Ϊ×îºóÒ»¸ö²ÎÊý£º
// domain/order.ts
¡ª ConardLi
export function createOrder(
user: User,
cart: Cart,
created: DateTimeString
): Order {
return {
user: user.id,
products,
created,
status: "new",
total: totalPrice(products),
};
}
|
ÕâÑùÎÒÃǾͲ»»áÆÆ»µÒÀÀµ¹æÔò£¬¼´Ê¹´´½¨ÈÕÆÚÒ²ÐèÒªÒÀÀµµÚÈý·½¿â£º
function someUserCase()
{
// Use the `dateTimeSource` adapter,
// to get the current date in the desired format:
const createdOn = dateTimeSource.currentDatetime();
// Pass already created date to the domain function:
createOrder(user, cart, createdOn);
}
|
Õâ»áÈÃÁìÓò±£³Ö¶ÀÁ¢£¬Ò²Ê¹²âÊÔ¸üÈÝÒס£
ÔÚÇ°ÃæµÄʾÀýÖУ¬ÎÒ²»ÕâÑù×öÓÐÁ½¸öÔÒò£ºËü»á·ÖÉ¢ÎÒÃǵÄÖØµã£¬Èç¹ûËüֻʹÓÃÓïÑÔ±¾ÉíµÄÌØÐÔ£¬ÎÒÈÏΪÒÀÀµÄã×Ô¼ºµÄ
Helper ûÓÐÈκÎÎÊÌâ¡£ÕâÑùµÄ Helper ÉõÖÁ¿ÉÒÔ±»ÊÓΪ¹²ÏíÄںˣ¬ÒòΪËüÃÇÖ»»á¼õÉÙ´úÂëµÄÖØ¸´¶È¡£
×¢Ò⹺Îï³µÓë¶©µ¥µÄ¹ØÏµ
ÔÚÕâ¸öСÀý×ÓÖУ¬Order »á°üº¬ Cart, ÒòΪ¹ºÎï³µÖ»±íʾ Product ÁÐ±í£º
export type
Cart = {
products: Product[];
};
export type Order = {
user: UniqueId;
cart: Cart;
created: DateTimeString;
status: OrderStatus;
total: PriceCents;
};
|
Èç¹û¹ºÎï³µÓÐÆäËûµÄºÍ¶©µ¥Ã»ÓйØÁªµÄÊôÐÔ£¬¿ÉÄÜ»á³öÎÊÌ⣬ËùÒÔÖ±½ÓÓà ProductList »á¸üºÏÀí£º
type ProductList
= Product[];
type Cart = {
products: ProductList;
};
type Order = {
user: UniqueId;
products: ProductList;
created: DateTimeString;
status: OrderStatus;
total: PriceCents;
};
|
ÈÃÓÃÀý¸ü·½±ã²âÊÔ
ÓÃÀýÒ²ÓкܶàÒªÌÖÂ۵ĵط½¡£±ÈÈ磬orderProducts º¯ÊýºÜÄѶÀÁ¢ÓÚ React À´²âÊÔ£¬Õⲻ̫ºÃ¡£ÀíÏëÇé¿öÏ£¬²âÊÔ²»Ó¦¸ÃÏûºÄÌ«¶àµÄ³É±¾¡£
ÎÊÌâµÄ¸ù±¾ÔÒòÎÒÃÇʹÓà Hooks À´ÊµÏÖÁËÓÃÀý£º
// application/orderProducts.ts
¡ª ConardLi
export function useOrderProducts() {
const notifier = useNotifier();
const payment = usePayment();
const orderStorage = useOrdersStorage();
const cartStorage = useCartStorage();
async function orderProducts(user: User, cart:
Cart) {
const order = createOrder(user, cart);
const paid = await payment.tryPay(order.total);
if (!paid) return notifier.notify("Oops!
const { orders } = orderStorage;
orderStorage.updateOrders([...orders, order]);
cartStorage.emptyCart();
}
return { orderProducts };
}
|
Ôڹ淶µÄʵÏÖÖУ¬ÓÃÀý·½·¨¿ÉÒÔ·ÅÔÚ Hooks µÄÍâÃæ£¬·þÎñͨ¹ý²ÎÊý»òÕßʹÓÃÒÀÀµ×¢Èë´«ÈëÓÃÀý£º
type Dependencies
= {
notifier?: NotificationService;
payment?: PaymentService;
orderStorage?: OrderStorageService;
};
async function orderProducts(
user: User,
cart: Cart,
dependencies: Dependencies = defaultDependencies
) {
const { notifier, payment, orderStorage } = dependencies;
// ...
}
|
È»ºó Hooks µÄ´úÂë¾Í¿ÉÒÔµ±×öÒ»¸öÊÊÅäÆ÷£¬Ö»ÓÐÓÃÀý»áÁôÔÚÓ¦Óò㡣orderProdeucts ·½·¨ºÜÈÝÒ׾ͿÉÒÔ±»²âÊÔÁË¡£
function useOrderProducts()
{
const notifier = useNotifier();
const payment = usePayment();
const orderStorage = useOrdersStorage();
return (user: User, cart: Cart) =>
orderProducts(user, cart, {
notifier,
payment,
orderStorage,
});
}
|
ÅäÖÃ×Ô¶¯ÒÀÀµ×¢Èë
ÔÚÓ¦Óò㣬ÎÒÃÇÊÇÊÖ¶¯½«ÒÀÀµ×¢Èë·þÎñµÄ£º
export function
useOrderProducts() {
// Here we use hooks to get the instances of each
service,
// which will be used inside the orderProducts
use case:
const notifier = useNotifier();
const payment = usePayment();
const orderStorage = useOrdersStorage();
const cartStorage = useCartStorage();
async function orderProducts(user: User, cart:
Cart) {
// ...Inside the use case we use those services.
}
return { orderProducts };
}
|
µ±È»»¹ÓиüºÃµÄ×ö·¨£¬ÒÀÀµ×¢Èë¿ÉÒÔ×Ô¶¯Íê³É¡£ÎÒÃÇÇ°ÃæÒѾͨ¹ý×îºóÒ»¸ö²ÎÊýʵÏÖÁË×î¼òµ¥µÄ×¢Èë°æ±¾£¬ÏÂÃæ¿ÉÒÔ½øÒ»²½ÅäÖÃ×Ô¶¯ÒÀÀµ×¢Èë¡£
ÔÚÕâ¸öÌØ¶¨µÄÓ¦ÓóÌÐòÖУ¬ÎÒÈÏΪÉèÖÃÒÀÀµ×¢ÈëûÓжà´óÒâÒå¡£Ëü»á·ÖÉ¢ÎÒÃǵÄ×¢ÒâÁ¦²¢Ê¹´úÂë¹ýÓÚ¸´ÔÓ¡£ÔÚʹÓÃÁË
React ºÍ hooks µÄÇé¿öÏ£¬ÎÒÃÇ¿ÉÒÔ½«ËüÃÇÓÃ×÷¡°ÈÝÆ÷¡±£¬·µ»ØÖ¸¶¨½Ó¿ÚµÄʵÏÖ¡£Êǵģ¬ËäÈ»»¹ÊÇÊÖ¶¯ÊµÏֵ쬵«Ëü²»»áÔö¼ÓÉÏÊÖÃż÷£¬²¢ÇÒ¶ÔÓÚÐÂÊÖ¿ª·¢ÈËÔ±À´ËµÔĶÁËٶȸü¿ì¡£
ʵ¼ÊÏîÄ¿ÖеÄÇé¿ö¿ÉÄܸü¸´ÔÓ
ÎÄÕÂÖеÄʾÀýÊǾ¹ý¾«¼òµÄ¶øÇÒÐèÇóÒ²±È½Ï¼òµ¥¡£ºÜÃ÷ÏÔ£¬ÎÒÃÇʵ¼Ê¿ª·¢ÖбÈÕâ¸öÀý×ÓÒª¸´ÔӵĶࡣËùÒÔÎÒ»¹Ïë̸̸ʵ¼Ê¿ª·¢ÖÐʹÓøɾ»¼Ü¹¹Ê±¿ÉÄܳöÏֵij£¼ûÎÊÌâ¡£
·ÖÖ§ÒµÎñÂß¼
×îÖØÒªµÄÎÊÌâÊÇÎÒÃǶÔÐèÇóµÄʵ¼Ê³¡¾°Ñо¿²»¹»ÉîÈë¡£ÏëÏóһϣ¬Ò»¼ÒÉ̵êÓÐÒ»¸ö²úÆ·¡¢Ò»¸ö´òÕÛ²úÆ·ºÍÒ»ÖÖÒѾעÏúµÄ²úÆ·¡£ÎÒÃÇÔõô׼ȷÃèÊöÕâЩʵÌ壿
ÊDz»ÊÇÓ¦¸ÃÓÐÒ»¸ö¿ÉÀ©Õ¹µÄ¡°»ù´¡¡±ÊµÌåÄØ£¿Õâ¸öʵÌ徿¾¹Ó¦¸ÃÔõôÀ©Õ¹£¿Ó¦¸ÃÓжîÍâµÄ×Ö¶ÎÂð£¿ÕâЩʵÌåÊÇ·ñÓ¦¸Ã»¥³â£¿
¿ÉÄÜÓÐÌ«¶àµÄÎÊÌâºÍÌ«¶àµÄ´ð°¸£¬Èç¹ûÖ»ÊǼÙÉ裬ÎÒÃDz»¿ÉÄÜ¿¼Âǵ½ËùÓеÄÇé¿ö¡£
¾ßÌå½â¾ö·½·¨»¹ÒªÊÓ¾ßÌåÇé¿ö¶ø¶¨£¬ÎÒÖ»ÄÜÍÆ¼ö¼¸¸öÎҵľÑé¡£
²»½¨ÒéʹÓü̳У¬¼´Ê¹Ëü¿´ÆðÀ´¿É¡°À©Õ¹¡±¡£
¸´ÖÆÕ³ÌùµÄ´úÂë²¢²»Ò»¶¨¶¼²»ºÃ£¬ÓÐʱºòÉõÖÁÄÜ·¢»Ó¸ü´óµÄ×÷Óᣴ´½¨Á½¸ö¼¸ºõÏàͬµÄʵÌ壬¹Û²ìËüÃÇÔÚÏÖʵÖеÄÐÐΪ¡£ÔÚijЩʱºò£¬ËüÃǵÄÐÐΪ¿ÉÄÜÇø±ðºÜ´ó£¬ÓÐʱºòÒ²¿ÉÄÜÖ»ÓÐÒ»Á½¸ö×ֶεÄÇø±ð¡£ºÏ²¢Á½¸ö·Ç³£ÏàËÆµÄʵÌå±Èд´óÁ¿µÄµÄ¼ì²éÒªÈÝÒ׺ܶࡣ
Èç¹ûÄãÒ»¶¨ÒªÀ©Õ¹Ò»Ð©ÄÚÈݵϰ¡£¡£
¼Ç×¡Ð±ä¡¢Äæ±äºÍ²»±ä£¬ÕâÑùÄã¾Í²»»á¶à³öһЩÒâÏë²»µ½µÄ¹¤×÷¡£
ÔÚ²»Í¬µÄʵÌåºÍ¿ÉÀ©Õ¹Ö®¼äÑ¡Ôñ£¬ÍƼöʹÓÃÀàËÆÓÚ BEM ÖеĿéºÍÐÞÊηû¸ÅÄîÀ´°ïÖúÄã˼¿¼£¬Èç¹ûÎÒÔÚ BEM
µÄÉÏÏÂÎÄÖп¼ÂÇËü£¬Ëü¿ÉÒÔ°ïÖúÎÒÈ·¶¨ÎÒÊÇ·ñÓÐÒ»¸öµ¥¶ÀµÄʵÌå»ò´úÂëµÄ¡°ÐÞÊηûÀ©Õ¹¡±¡£

BEM - Block Element Modfier£¨¿éÔªËØ±à¼Æ÷£©ÊÇÒ»¸öºÜÓÐÓõķ½·¨£¬Ëü¿ÉÒÔ°ïÖúÄã´´½¨³ö¿ÉÒÔ¸´ÓõÄǰ¶Ë×é¼þºÍǰ¶Ë´úÂë¡£
Ï໥ÒÀÀµµÄÓÃÀý
µÚ¶þ¸öÎÊÌâÊÇÓÃÀýÏà¹ØµÄ£¬Í¨¹ýÒ»¸öÓÃÀýµÄʼþ´¥·¢ÁíÒ»¸öÓÃÀý¡£
ÎÒÖªµÀ²¢ÇÒ¶ÔÎÒÓаïÖúµÄ´¦ÀíÕâ¸öÎÊÌâµÄΨһ·½·¨Êǽ«ÓÃÀý·Ö½âΪ¸üСµÄÔ×ÓÓÃÀý¡£ËüÃǽ«¸üÈÝÒ××éºÏÔÚÒ»Æð¡£
ͨ³££¬³öÏÖÕâ¸öÎÊÌâÊDZà³ÌÖÐÁíÍâÒ»¸ö´óÎÊÌâµÄ½á¹û¡£Õâ¾ÍÊÇʵÌå×éºÏ¡£
×îºó
ÔÚ±¾ÎÄÀÎÒÃǽéÉÜÁËǰ¶ËµÄ¡°¸É¾»¼Ü¹¹¡±¡£
Õâ²»ÊÇÒ»¸ö»Æ½ð±ê×¼£¬¶øÊÇÒ»¸öÔںܶàµÄÏîÄ¿¡¢¹æ·¶ºÍÓïÑÔÉÏ»ýÀ۵ľÑé»ã×Ü¡£
ÎÒ·¢ÏÖËüÊÇÒ»Öַdz£·½±ãµÄ·½°¸£¬¿ÉÒÔ°ïÖúÄã½âñîÄãµÄ´úÂë¡£Èò㡢ģ¿éºÍ·þÎñ¾¡Á¿¶ÀÁ¢¡£²»½ö¿ÉÒÔ¶ÀÁ¢·¢²¼¡¢²¿Ê𣬻¹¿ÉÒÔÈÃÄã´ÓÒ»¸öÏîÄ¿Ç¨ÒÆÁíÒ»¸öÏîÄ¿µÄʱºòÒ²¸ü¼ÓÈÝÒס£
ÄãÀíÏëϵÄǰ¶Ë¼Ü¹¹ÊÇʲôÑùµÄÄØ£¿ |