²»Í¬ÓÚÆäËüµÄ¼Ü¹¹·½·¨£¬ÁìÓòÇý¶¯Éè¼ÆDDD(Domain
Driven Design)Ìá³öÁË´ÓÒµÎñÉè¼Æµ½´úÂëʵÏÖÒ»ÖÂÐÔµÄÒªÇ󣬲»ÔÙ¶Ô·ÖÎöÄ£ÐͺÍʵÏÖÄ£ÐͽøÐÐÇø·Ö¡£Ò²¾ÍÊÇ˵´Ó´úÂëµÄ½á¹¹ÖÐÎÒÃÇ¿ÉÒÔÖ±½ÓÀí½âÒµÎñµÄÉè¼Æ£¬ÃüÃûµÃµ±µÄ»°£¬·Ç³ÌÐòÈËÔ±Ò²¿ÉÒÔ¡°¶Á¡±´úÂë¡£

È»¶øÔÚÕû¸öDDDµÄ½¨Ä£¹ý³ÌÖУ¬ÎÒÃǸü¶à¹Ø×¢µÄÊǺËÐÄÁìÓòÄ£Ð͵Ľ¨Á¢£¬ÎÒÃÇÈÏΪÍê³ÉÒµÎñµÄÐèÇó¾ÍÊÇÔÚÁìÓòÄ£ÐÍÉϵÄһϵÁвÙ×÷(Ó¦ÓÃ)¡£ÕâЩ²Ù×÷°üÀ¨Á˶ԺËÐÄʵÌå״̬µÄ¸Ä±ä£¬ÁìÓòʼþµÄ´æ´¢£¬ÁìÓò·þÎñµÄµ÷Óõȡ£ÔÚÁ¼ºÃµÄÁìÓòÄ£ÐÍÖ®ÉÏ£¬ÊµÏÖÕâЩӦÓÃÓ¦¸ÃÊÇÇáËɶøÓä¿ìµÄ¡£
±ÊÕß¾Àú¹ýºÜ¶à´ÎDDDµÄ½¨Ä£¹¤×÷·»£¬ÔÚ¾ÀúÁËÊýÌìÒ»ÂÖÓÖÒ»ÂÖ¼¤ÁÒÌÖÂۺͲ»ÑáÆä·³µÄÉóÊÓÖ®ºó£¬´ó¼ÒÐÀοµØ¿´×ŰװåÉϸ÷ÖÖÑÕɫֽÌùËùչʾ³öÀ´µÄÁìÓòÄ£ÐÍ£¬³É¾Í¸ÐдÂú´ó¼ÒµÄÁ³ÅÓ¡£¾ÍÔÚÕâ¸ö´ó¹¦¸æ³ÉµÄʱ¿Ì£¬ÍùÍù»áÓÐÈËÎÊ£ºÕâ¸öÄ£ÐÍÎÒÃÇÔõôÂ䵨Ĩ?È»ºó´ó¼ÒÁ³ÉϵÄÓäÔÃÏûʧÁË£¬»»ÉÏÁ˶Ôϸ½Ú¾ÍÊÇħ¹íµÄ½¹ÂÇ¡£µ«ÕâÊÇÎÒÃDz»¿É±ÜÃâµÄʵÏÖϸ½Ú£¬DDDµÄÔʼ·½·¨ÂÛÖÐËäÈ»¸ø³öÁË¡°·Ö²ã¼Ü¹¹¡±(Layered
Architecture)µÄԪģÐÍ£¬µ«ÈçºÎ·Ö²ãȴûÓÐÃ÷È·¶¨Òå¡£
·Ö²ã¼Ü¹¹
ÔÚDDD·½·¨Ìá³öºóµÄÊýÄêÀ·Ö²ã¼Ü¹¹µÄ¾ßÌåʵÏÖÒ²¾ÀúÁ˼¸´úÑݽø£¬Ö±µ½Martin FowlerÌáÁ¶³öÏÂͼµÄ·Ö²ãʵÏּܹ¹ºó£¬²ÅÖð²½Îª´ó¼ÒËùÈϿɡ£DDDµÄ·½·¨Ò²µÃµ½ÁËÓÐЧµÄ²¹³ä£¬Ä£ÐÍÂ䵨µÄÎÊÌâÒ²±äµÃ¸üÈÝÒ×£¬ºËÐÄÁìÓòÄ£Ð͵ķ¶Î§Ò²×ö³öÁ˱ȽÏÃ÷È·µÄ¶¨Ò壺°üÀ¨ÁËDomain£¬Service
LayerºÍRepositories¡£

(Martin Fowler×ܽáÌá³öµÄ·Ö²ã¼Ü¹¹ÊµÏÖ£¬×¢Òâ¡°Resources¡±ÊÇ»ùÓÚRESTful¼Ü¹¹µÄ³éÏó£¬ÎÒÃÇÒ²¿ÉÒÔÀí½âΪ¸üͨÓõÄÕë¶ÔÍâ½çµÄ½Ó¿ÚInterface¡£¶øHTTP
ClientÖ÷ÒªÊÇÕë¶Ô»¥ÁªÍøµÄͨÐÅÐÒ飬Gatewaysʵ¼Ê²ÅÊǽ»»»¹ý³ÌÖÐ×é×°ÐÅÏ¢µÄÂß¼ËùÔÚ¡£)
ÎÒÃǵĺËÐÄʵÌå(Entity)ºÍÖµ¶ÔÏó(Value Object)Ó¦¸ÃÔÚDomain²ã£¬¶¨ÒåµÄÁìÓò·þÎñ(Domain
Service)ÔÚService Layer£¬¶øÕë¶ÔʵÌåºÍÖµ¶ÔÏóµÄ´æ´¢ºÍ²éѯÂß¼¶¼Ó¦¸ÃÔÚRepositories²ã¡£ÖµµÃ×¢ÒâµÄÊÇ£¬²»Òª°ÑEntityµÄÊôÐÔºÍÐÐΪ·ÖÀëµ½DomainºÍServiceÁ½²ãÖÐȥʵÏÖ£¬¼´ËùνµÄƶѪģÐÍ£¬ÊÂʵ֤Ã÷ÕâÑùµÄʵÏÖ·½Ê½»áÔì³ÉºÜ´óµÄά»¤ÎÊÌâ¡£DDDÕ½Êõ½¨Ä£ÖеÄԪģÐͶ¨Òå²»Ó¦¸ÃÔÚʵÏÖ¹ý³ÌÖб»¸Ä±ä£¬×÷ΪԪģÐÍÖÐÔªËØÖ®Ò»µÄʵÌå±¾Éí¾ÍÓ¦¸Ã°üº¬Õë¶Ô×ÔÉíµÄÐÐΪ¶¨Òå¡£
»ùÓÚÕâ¸öÄ£ÐÍ£¬ÏÂÃæÎÒÃÇÀ´Ì¸Ì¸¸ü¾ßÌåµÄ´úÂë½á¹¹¡£¶ÔÓÚÕâ¸ö·Ö²ã¼Ü¹¹»¹ÓÐÒÉ»óµÄ¶ÁÕß¿ÉÒÔ¾«¶ÁÒ»ÏÂMartinµÄ
ÔÎÄ ¡£ÓÐÒâ˼µÄÒ»µãÊÇ£¬Õâ¸öÄ£Ð͵ÄÐðÊöʵ¼ÊÊÇÔÚ΢·þÎñ¼Ü¹¹µÄ²âÊÔÎÄÕÂÖУ¬ÆäÖÐÉîÒâÖµµÃ´ó¼ÒÌå»á¡£
ÕâÀïÐèÒªÃ÷È·µÄÊÇ£¬ÎÒÃÇ̸ÂÛ´úÂë½á¹¹µÄʱºò£¬Õë¶ÔµÄÊÇÒ»¸ö¾¹ýDDD½¨Ä£ºóµÄ×ÓÎÊÌâÓò(²Î¼ûÕ½ÂÔÉè¼ÆÆª)£¬ÕâÊÇÎÒÃÇÃ÷È·µÄ×é¼þ»¯±ß½ç¡£ÊÇ·ñ½øÒ»²½×é¼þ»¯£¬±ÈÈç°´ÕÕÏÞ½çÉÏÏÂÎÄ(Bounded
Context)Ä£¿é»¯£¬»ò²ÉÓÃ΢·þÎñ¼Ü¹¹·þÎñ»¯£¬ºËÐÄʵÌå¶¼ÊǽøÒ»²½¿ÉÄܲÉÓõÄ×é¼þ»¯·½·¨¡£´Ó³éÏó²ãÃæ½²£¬ÀÏÂíÌáÁ¶µÄ·Ö²ã¼Ü¹¹ÊÊÓÃÓÚÃæÏòÒµÎñµÄ·þÎñ»¯¼Ü¹¹£¬ËùÒÔÈç¹ûÒª½øÒ»²½×é¼þ»¯Ò²ÊÇ¿ÉÒÔ°´ÕÕÕâ¸ö´úÂë½á¹¹À´Íê³ÉµÄ¡£
×ÜÌåµÄ´úÂëĿ¼½á¹¹ÈçÏ£º
-
DDD-Sample/src/
domain
gateways
interface
repositories
services |
Õâ¸öĿ¼½á¹¹Ò»Ò»¶ÔÓ¦ÁËǰÎĵķֲã¼Ü¹¹Í¼¡£ÍêÕûµÄ°¸Àý´úÂëÇë´ÓGitHub ÏÂÔØ ¡£
¿ÉÒÔ¿´µ½Êµ¼ÊÉÏÎÒÃDz¢Ã»Óн¨Á¢Íⲿ´æ´¢(Data Mappers/ORM)ºÍ¶ÔÍâͨÐÅ(HTTP Client)µÄĿ¼¡£´ÓÁìÓòÄ£ÐͺÍÓ¦ÓõĽǶȣ¬ÕâÁ½Õß¶¼ÊÇÎÒÃDz»±Ø¹ØÐĵģ¬Äܹ»ÑéÖ¤Õû¸öÁìÓòÄ£Ð͵ÄÊäÈëºÍÊä³ö¾Í×ã¹»ÁË¡£ÖÁÓÚʲôÑùµÄÍⲿ´æ´¢ºÍÍⲿͨÐÅ»úÖÆÊÇ¿ÉÒÔ±»¡°×¢È롱µÄ¡£ÕâÑùµÄ¸ôÀëÊÇʵÏֿɶÀÁ¢²¿Êð·þÎñµÄ»ù´¡£¬Ò²ÊÇÎÒÃÇÄܹ»²âÊÔÁìÓòÄ£ÐÍʵÏÖµÄÒªÇó¡£

Ä£Ðͱí´ï
¸ù¾Ý·Ö²ã¼Ü¹¹È·Á¢ÁË´úÂë½á¹¹ºó£¬ÎÒÃÇÐèÒªÊ×Ïȶ¨ÒåÇå³þÎÒÃǵÄÄ£ÐÍ¡£ÈçÇ°Ãæ½²µ½µÄ£¬ÕâÀïÖ÷񻃾¼°µÄÊÇ´ÓÕ½Êõ½¨Ä£¹ý³ÌÖеõ½µÄºËÐÄʵÌåºÍ·þÎñµÄ¶¨Òå¡£ÎÒÃÇÀûÓÃC++Í·Îļþ(.hÎļþ)À´Õ¹Ê¾Ò»¸öDomainÄ£Ð͵͍Ò壬°¸ÀýÁé¸ÐÀ´Ô´ÓÚDDDÔÖøÀïµÄ¼¯×°Ïä»õÔËÀý×Ó¡£
namespace
domain{
struct Entity
{
int getId();
protected:
int id;
};
struct AggregateRoot: Entity
{
};
struct ValueObject
{
};
struct Provider
{
};
struct Delivery: ValueObject
{
Delivery(int);
int AfterDays;
};
struct Cargo: AggregateRoot
{
Cargo(Delivery*, int);
~Cargo();
void Delay(int);
private:
Delivery* delivery;
};
} |
Õâ¸öʵÏÖÊ×ÏÈÉêÃ÷ÁËԪģÐÍʵÌåEntityºÍÖµ¶ÔÏóValueObject¡£ÊµÌåÒ»¶¨»áÓÐÒ»¸ö±êʶid¡£ÔÚʵÌåµÄ»ù´¡ÉÏÉùÃ÷ÁËDDDÖеÄÖØÒªÔªËØ¾ÛºÏ¸ù
AggregateRoot¡£¸ù¾Ý¶¨Ò壬¾ÛºÏ¸ù±¾Éí¾ÍÓ¦¸ÃÊÇÒ»¸öʵÌ壬ËùÒÔAggregateRoot¼Ì³ÐÁËEntity¡£
Õâ¸ö°¸ÀýÖÐÎÒÃǶ¨ÒåÁËÒ»¸öʵÌåCargo£¬Í¬Ê±Ò²ÊÇÒ»¸ö¾ÛºÏ¸ù¡£DeliveryÊÇÒ»¸öÖµ¶ÔÏó¡£ËäÈ»ÕâÀïΪÁËʵÏÖЧÂʲÉÓõÄÊÇstruct£¬ÔÚC++Àï¿ÉÒÔÀí½âΪ¶¨ÒåÒ»¸öclassÀà¡£
ÒÀÀµ¹ØÏµ
´úÂëĿ¼½á¹¹²¢²»Äܱí´ï·Ö²ãÌåϵÖи÷²ãµÄÒÀÀµ¹ØÏµ£¬±ÈÈçDomain²ãÊDz»Ó¦¸ÃÒÀÀµÓÚÆäËüÈκÎÒ»²ãµÄ¡£Î¬»¤¸÷²ãµÄÒÀÀµ¹ØÏµÊÇÖÁ¹ØÖØÒªµÄ£¬ºÜ¶àÍŶÓÔÚʵʩµÄ¹ý³ÌÖж¼Ã»ÓÐÄܹ»½¨Á¢ÆðÕâÑùµÄ¹¤³Ì¼ÍÂÉ£¬×îºóÔì³É´úÂë½á¹¹µÄ»ìÂÒ£¬ÁìÓòÄ£ÐÍÒ²±»´òÆÆ¡£
¸ù¾Ý·Ö²ã¼Ü¹¹µÄ¹æÔò£¬ÎÒÃÇ¿ÉÒÔ¿´µ½Ê¾ÀýÖеĴúÂë½á¹¹ÈçÏÂͼ¡£

DomainÊDz»ÒÀÀµÓÚÈÎºÎµÄÆäËü¶ÔÏóµÄ¡£RepositoriesÊÇÒÀÀµÓÚDomainµÄ£¬ÊµÏÖÈçÏ£ºÒýÓÃÁËmodel.h¡£
#include
"model.h"
#include <vector>
using namespace domain;
namespace repositories {
struct Repository
{
};
... |
ServicesÊÇÒÀÀµÓÚDomainºÍRepositoriesµÄ£¬ÊµÏÖÈçÏ£ºÒýÓÃÁËmodel.hºÍrepository.h
#include
"model.h"
#include "repository.h"
using namespace domain;
using namespace repositories;
namespace services {
struct CargoProvider : Provider {
virtual void Confirm(Cargo* cargo){};
};
struct CargoService {
... ...
};
... |
ΪÁËά»¤ºÏÀíµÄÒÀÀµ¹ØÏµ£¬ÒÀÀµ×¢Èë(Depedency Injection)ÊÇÐèÒª¾³£²ÉÓõÄʵÏÖģʽ£¬Ëü×÷Ϊ½âñîºÏµÄÒ»ÖÖ·½·¨ÏàÐÅ´ó¼Ò¶¼²»»áİÉú£¬¾ßÌ嶨Òå²Î¼û
ÕâÀï ¡£
ÔÚ²âÊÔ¹¹½¨Ê±£¬ÎÒÃÇÀûÓÃÁËÒ»¸öIoC¿ò¼Ü(ÒÀÀµ×¢ÈëµÄʵÏÖ)À´¹¹ÔìÁËÒ»¸öApi£¬²¢ÇÒ°ÑÏà¹ØµÄÒÀÀµ(ÈçCargoService)×¢Èë¸øÁËÕâ¸öApi¡£ÕâÑù¼ÈûÓÐÆÆ»µInterfaceºÍServiceµÄµ¥ÏòÒÀÀµ¹ØÏµ£¬ÓÖ½â¾öÁ˲âÊÔ¹ý³ÌÖÐApiµÄʵÀý»¯ÒªÇó¡£
auto
provider = std::make_shared< StubCargoProvider
>();
api::Api* createApi() {
ContainerBuilder builder;
builder.registerType< CargoRepository >().singleInstance();
builder.registerInstance(provider).as<CargoProvider>();
builder.registerType< CargoService >().singleInstance();
builder.registerType<api::Api>().singleInstance();
auto container = builder.build();
std::shared_ptr<api::Api> api = container->resolve<api::Api>();
return api.get();
} |
²âÊÔʵÏÖ
ÓÐÁËÁìÓòÄ£ÐÍ£¬´ó¼Ò×ÔÈ»»áÏë×ÅÈçºÎȥʵÏÖÒµÎñÓ¦ÓÃÁË£¬¶øÊµÏÖÓ¦ÓõĹý³ÌÖÐÒ»¶¨»á¿¼Âǵ½µ¥Ôª²âÊÔµÄÉè¼Æ¡£ÔÚ¹¹½¨¸ßÖÊÁ¿Èí¼þ¹ý³ÌÖУ¬µ¥Ôª²âÊÔÒѾ³ÉΪÁ˱ê×¼¹æ·¶£¬µ«¸ßÖÊÁ¿µÄµ¥Ôª²âÊÔÈ´ÊÇÀ§ÈźܶàÍŶӵįձéÎÊÌâ¡£ºÜ¶àʱºòÉè¼Æ²âÊÔ±ÈʵÏÖÓ¦Óñ¾Éí¸ü¼ÓÀ§ÄÑ¡£
ÕâÀïºÜÄÑÓÐÒ»¸ö¹Ì¶¨±ê×¼À´ÆÀÅÐij¸öʱ¼äµãµÄµ¥Ôª²âÊÔÖÊÁ¿£¬µ«Ò»¸öºËÐĵÄÔÔòÊÇÈÃÓÃÀý¾¡Á¿²âÊÔÒµÎñÐèÇó¶ø²»ÊÇʵÏÖ·½Ê½±¾Éí¡£Âú×ãÒµÎñÐèÇóÊÇÎÒÃǵÄÄ¿±ê£¬ÊµÏÖ·½Ê½¿ÉÄÜÓжàÖÖ£¬ÎÒÃDz»Ï£ÍûÐèÒª³ÖÐøÖØ¹¹µÄʵÏÖ´úÂëÓ°Ïìµ½ÎÒÃǵIJâÊÔÓÃÀý¡£±ÈÈçÕë¶ÔʵÏÖ¹ý³ÌÖеÄij¸öº¯Êý½øÐÐÈë²ÎºÍ³ö²ÎµÄµ¥Ôª²âÊÔ£¬µ±Õâ¸öº¯Êý·¢ÉúÒ»µã¸Ä±ä(¼´Ê¹ÊÇÖØÃüÃû)£¬ÎÒÃÇÒ²ÐèÒª¸Ä¶¯²âÊÔ¡£

²âÊÔÇý¶¯¿ª·¢TDDÎÞÒÉÊÇÒ»ÖֺõÄʵ¼ù£¬Èç¹ûÓ¦Óõõ±£¬ËüȷʵÄܹ»ÊµÏÖÎÒÃÇÉÏÊöµÄÔÔò£¬²¢ÇÒÄܹ»°ïÖúÎÒÃǽ»Á÷ÒµÎñµÄÐèÇ󡣱ȽÏÓÐÒâ˼µÄÊÇ£¬ÔÚ»ùÓÚDDD½¨Á¢µÄºËÐÄÄ£ÐÍÖ®ÉÏÓ¦ÓÃTDDËÆºõ¸ü¼Ó˳Àí³ÉÕ¡£Àà±ÈDDDºÍTDDËäÈ»ÊDz»Ç¡µ±µÄ£¬µ«ÎÒÃǻᷢÏÖÁ½ÕßÔÚ×ñѵÄÔÔòÉÏÊÇÒ»Öµģ¬¼´¶¼ÊÇÃæÏòÒµÎñ×ö·Ö½âºÍÉè¼Æ£ºDDD¾ÍÕû¸öÒµÎñÎÊÌâÓò½øÐÐÁ˷ֽ⣬ÐγÉ×ÓÎÊÌâÓò;TDD¾ÍÒµÎñÐèÇóÔÚʵÏÖʱ½øÐÐÈÎÎñ·Ö½â£¬´Ó¼òµ¥³¡¾°µ½¸´ÔÓ³¡¾°Öð²½Í¨¹ý²âÊÔÇý¶¯³öʵÏÖ¡£ÏÂÃæµÄ²âÊÔÓÃÀýÕ¹ÏÖÁËÔÚºËÐÄÄ£ÐÍÉϵÄTDD¹ý³Ì¡£
TEST(bc_demo_test,
create_cargo)
{
api::CreateCargoMsg* msg = new api::CreateCargoMsg();
msg->Id = ID;
msg->AfterDays = AFTER_DAYS;
createCargo(msg);
EXPECT_EQ(msg->Id, provider->cargo_id);
EXPECT_EQ(msg->AfterDays, provider->after_days);
} |
ÉÏÃæ²âÊÔÁËÊÕµ½Ò»Ìõ´´½¨ÐÅÏ¢ºóʵÀý»¯Ò»¸öCargoµÄ¼òµ¥³¡¾°£¬ÒªÇó´´½¨ºóµÄCargoµÄ±êʶid¸úÐÅÏ¢ÀïµÄÒ»Ö£¬²¢ÇÒ³ö»õµÄÈÕÆÚÒ»Ö¡£Õâ¸ö²âÊÔÇý¶¯³öÀ´Ò»¸öInterfaceµÄApi::CreateCargo¡£
ÏÂÃæÊÇÁíÍâÒ»¸ö²âÊÔÍÆ³ÙdelayµÄ³¡¾°£¬Í¬ÑùÎÒÃÇ¿´µ½ÁËÇý¶¯³öµÄApi::DelayµÄʵÏÖ¡£
TEST(bc_demo_test,
delay_cargo)
{
api::Api* api = createApi();
api::CreateCargoMsg* msg = new api::CreateCargoMsg();
msg->Id = ID;
msg->AfterDays = AFTER_DAYS;
api->CreateCargo(msg);
api->Delay(ID,2);
EXPECT_EQ(ID, provider->cargo_id);
EXPECT_EQ(12, provider->after_days);
} |
³¤ÆÚÒÔÀ´¶ÔÓÚTDDÕâ¸öʵ¼ù´ó¼Ò¶¼Óмܹ¹Éè¼ÆÉϵÄÒɻ󣬺ܶà×ÊÉî¼Ü¹¹Ê¦µ£ÐÄÍêÈ«´ÓÒµÎñÐèÇóÇý¶¯³öʵÏÖû·¨ÐγÉÓÐЧµÄ¼¼Êõ¼Ü¹¹£¬¶øÇÒÿ´ÎʵÏÖµÄÖØ¹¹³É±¾¶¼¿ÉÄܸܺߡ£DDDµÄÒýÈë´ÓijÖ̶ֳÈÉϽâ¾öÁËÕâ¸ö¹ËÂÇ£¬Í¨¹ýǰÆÚµÄÕ½ÂÔºÍÕ½Êõ½¨Ä£È·¶¨Á˺ËÐÄÁìÓò¼Ü¹¹£¬Õâ¸ö¼Ü¹¹ÊÇͨ¹ýÔ¤ÏÈ×ÛºÏÌÖÂÛ¾ö²ßµÄ£¬¿¼ÂÇÁ˸ü¹ãÀ«µÄÒµÎñÎÊÌ⣬½ÏÖ®TDDÓ¦ÓõÄÒµÎñÐèÇó²ãÃæ¸ü¼Óºê¹Û¡£ÔÚÒÑÓкËÐÄÄ£ÐÍ»ù´¡ÉÏÎÒÃÇÒ²»á·¢ÏÖ²âÊÔÓÃÀýµÄÉè¼Æ¸üÈÝÒ×´ÓÓ¦ÓÃÊӽdzö·¢£¬´Ó¶ø½µµÍÁ˲âÊÔÉè¼ÆµÄÄѶȡ£
¹ØÓÚÔ¤ÏÈÉè¼Æ
Èç¹ûûÓжÁÕ½ÂÔÆªÖ±½Ó¿´±¾ÎĵĶÁÕ߿϶¨»áÌá³ö¹ØÓÚÔ¤ÏÈÉè¼ÆµÄ¹ËÂÇ£¬±Ï¾¹DDDÊDZ»Ãô½Ý¿ª·¢È¦×ÓÈϿɵÄÒ»Öּܹ¹·½Ê½£¬ÆäÄ¿±êÓ¦¸ÃÊǹ¹½¨¼Ü¹¹Ä£Ð͵ÄÏìÓ¦Á¦¡£¶øÕâÀï¸ø´ó¼ÒµÄ¸ü¶àÊÇģʽ»¯µÄʵÏÖ¹ý³Ì£¬ºÃËÆ´Ó½¨Ä£µ½´úÂëÒ»Çж¼Ô¤ÏÈÉè¼ÆºÃÁË¡£
ÖµµÃÇ¿µ÷µÄÊÇ£¬ÎÒÃÇÈÔÈ»·´¶ÔǰÆÚÉè¼ÆµÄ´ó¶øÈ«(Big-Design-Up-Front£¬BDUF)¡£ µ«ÎÒÃÇÓ¦¸ÃÈÏ¿ÉǰÆÚ¶ÔºËÐÄÁìÓòÄ£Ð͵ķÖÎöºÍÉè¼Æ£¬ÕâÑùÄܹ»°ïÖúÎÒÃǸü¿ìµØÏìÓ¦ºóÐøµÄÒµÎñ±ä»¯(¼´ÔÚºËÐÄÄ£ÐÍÖ®ÉϵÄÓ¦ÓÃ)¡£Õâ²»´ú±íןËÐÄÁìÓòÄ£ÐÍδÀ´»áÒ»³É²»±ä£¬»òÕß²»Äܸı䣬¶øÊǾ¹ýͳһ½¨Ä£µÄºËÐIJ¿·Ö±ä»¯ÆµÂʽÏÖ®ÍⲿӦÓûáµÍºÜ¶à¡£Èç¹ûºËÐÄÁìÓòÄ£ÐÍÒ²±ä»¯¾çÁÒ£¬ÄÇôÎÒÃÇ¿ÉÄܾÍÒª¿¼ÂÇÊÇ·ñÒµÎñ·¢ÉúÁ˸ù±¾ÐԵı仯£¬ÐèÒª½¨Á¢ÐµÄÄ£ÐÍ¡£
ÁíÍâ²»ÄÜÍü¼ÇÎÒÃÇÔ¤Ïȶ¨ÒåµÄÄ£ÐÍÒ²ÊDZ»¾ÖÏÞÔÚÒ»¸ö·Ö½â³öÀ´µÄºËÐÄÎÊÌâÓòÀïµÄ£¬Ò²¾ÍÊÇ˵ÎÒÃDz¢²»Ï£ÍûÒ»¿ÚÆø°ÑÕû¸ö¸´ÔÓµÄÒµÎñÁìÓòÀïµÄËùÓÐÄ£ÐͶ¼½¨Á¢ÆðÀ´¡£ÕâÖÖ·¶Î§µÄ¾ÖÏÞijÖ̶ֳÈÉÏÒ²ÏÞÖÆÁËÎÒÃÇÔ¤ÏÈÉè¼ÆµÄ·¶Î§£¬´ÙʹÎÒÃǸü¶àÓõü´úµÄ·½Ê½À´¿´´ý½¨Ä£¹¤×÷±¾Éí¡£
×îºóÏÔÈ»ÎÒÃÇÓ¦¸ÃÓÐÒ»¸öºËÐÄÍŶÓÀ´ÊØ»¤ºËÐÄÁìÓòÄ£ÐÍ£¬Õâ²»´ú±í×ÅÈκÎÄ£Ð͵ÄÉè¼ÆºÍ¸Ä¶¯¶¼±ØÐëÓÉÕâ¸öÍŶӵÄÈË×ö³ö(ËäÈ»Óв»ÉÙµÄÍŶÓȷʵÊÇÕâÑùÂ䵨DDDµÄ)¡£ÎÒÃÇÆÚÍûµÄÊÇÈκζԺËÐÄÄ£Ð͵ĸ͝¶¼Äܹ»Í¨¹ýÕâ¸öºËÐÄÍŶÓÀ´´Ù½ø¸ü´ó·¶Î§µÄ½»Á÷ºÍ¹µÍ¨¡£¼ìÑéÒ»¸öÄ£ÐÍÊÇ·ñÂ䵨µÄΨһ±ê×¼ÊÇÓ¦ÓÃÕâ¸öÄ£Ð͵ÄÍŶÓÄÜ·ñ¾ÍÄ£Ðͱ¾Éí´ï³É¹²Ê¶¡£ÔÚÕâµãÉÏÎÒÃÇ¿´µ½ºÜ¶àÍŶӳÖÐøÍ¨¹ý´úÂë×ß²é(code
review)µÄ·½Ê½ÔÚÏßÉϺÍÏßÏÂʵ¼ù»ùÓÚºËÐÄÄ£Ð͵Ľ»Á÷£¬´Ó¶øÆðµ½ÁËÕæÕýÒâÒåÉϵġ°ÊØ»¤¡±×÷Óã¬ÈÃÄ£Ðͱ¾Éí³ÉΪÍŶӵĹ²Í¬ÔðÈΡ£
ʵ¼ùDDDʱÈÔÈ»ÐèÒª×ñÑ¡°Ä£ÐÍÊÇÓÃÀ´½»Á÷µÄ¡±µÄÕâÒ»ºËÐÄÔÔò¡£ÎÒÃÇÏ£Íû±¾ÎĽéÉܵķ½·¨¼°Ä£Ê½Äܹ»°ïÖú´ó¼Ò¸üÈÝÒ׵ؽ»Á÷ÁìÓòÄ£ÐÍ£¬Ò²ËãÊǶÔDDDÕ½ÂÔºÍÕ½ÊõÉè¼ÆµÄÒ»µã²¹³ä¡£ |