字符串作為價(jià)值對(duì)象:一種現(xiàn)代的特定領(lǐng)域字符串類型的方法
Aug 01, 2025 am 07:48 AM應(yīng)用價(jià)值對(duì)象代替域驅(qū)動(dòng)的應(yīng)用程序中的原始字符串,以防止錯(cuò)誤並提高類型安全性; 1。使用原始字符串會(huì)導(dǎo)致原始癡迷,其中可互換的字符串類型會(huì)導(dǎo)致諸如參數(shù)交換之類的微妙錯(cuò)誤; 2。諸如EmailAddress之類的值對(duì)象封裝了特定於域特定的字符串,並具有驗(yàn)證,不變性和有意義的語(yǔ)義; 3。福利包括類型安全,集中驗(yàn)證,通過(guò)記錄的不變性,更好的可發(fā)現(xiàn)性和一致的格式; 4。可以為域邏輯添加諸如ISCorporate之類的輔助方法; 5。諸如C#記錄之類的現(xiàn)代語(yǔ)言功能減少了樣板,而隱式運(yùn)算符和在EF核心支持無(wú)縫互動(dòng)的ORM中的價(jià)值轉(zhuǎn)換; 6。標(biāo)準(zhǔn)化確保一致的格式,序列化庫(kù)可以通過(guò)自定義轉(zhuǎn)換器處理這些類型; 7.源生成器可以自動(dòng)化重複代碼,從而使採(cǎi)用更加容易; 8.從電子郵件或Phonenumber等關(guān)鍵類型開始,在清晰,正確性和可維護(hù)性方面表現(xiàn)出明顯的好處,證明特定於域特異性的字符串應(yīng)獲得專用類型。
在域驅(qū)動(dòng)的應(yīng)用程序中使用字符串時(shí),很容易將它們視為原始的,可互換的值 - 在變量,參數(shù)和數(shù)據(jù)庫(kù)字段之間自由分配。但這導(dǎo)致了細(xì)微的錯(cuò)誤,類型安全性差和難以推斷的代碼。一種現(xiàn)代,更強(qiáng)大的方法是將特定於領(lǐng)域的字符串視為價(jià)值對(duì)象。

我們沒(méi)有將string
直接用於電子郵件地址,電話號(hào)碼或ID之類的內(nèi)容,而是將其包裝在專用類型中。這為我們提供了更好的正確性,清晰度和控制。
為什麼原弦有問(wèn)題
到處使用普通字符串似乎無(wú)害,但請(qǐng)考慮一下:

字符串userId =“ jane.doe@example.com”; 字符串電子郵件=“ 12345”; sendemail(電子郵件,用戶ID);
等等 - 我們只是互換了論點(diǎn)嗎?編譯器不會(huì)抓住這個(gè)。兩者都是string
,因此它們可以互換,即使它們代表了非常不同的概念。
這是原始的癡迷代碼氣味:在內(nèi)置類型上過(guò)度融合而不是建模域概念。

價(jià)值對(duì)物體救援
值對(duì)象表示由其值而不是身份定義的有意義的域數(shù)據(jù)。對(duì)於字符串,這意味著將它們包裹在強(qiáng)制執(zhí)行規(guī)則的輕巧,不變的類型中。
例如, EmailAddress
值對(duì)象:
公共記錄電子郵件address(字符串值) { 公共靜態(tài)bool tryparse(字符串輸入,out emailaddress?電子郵件) { 電子郵件= null; if(string.isnullorwhitespace(input))返回false; 嘗試 { var addr = new system.net.mail.mailaddress(input); if(addr.address ==輸入) { email = new emailAddress(input.trim()); 返回true; } } 抓住 { } 返回false; } 公共覆蓋字符串toString()=> value; }
現(xiàn)在,而不是:
void sendemail(字符串到,字符串,從)
我們有:
void sendemail(電子郵件address to,emailaddress from)
現(xiàn)在,功能簽名意味著一些。您不能意外地通過(guò)預(yù)期電子郵件的用戶ID。
特定領(lǐng)域字符串類型的好處
- 類型安全:編譯器可防止混合不同種類的字符串。
- 封裝:驗(yàn)證邏輯生存在一個(gè)位置 - 值對(duì)象。
- 不變性:記錄(在C#中)或類似構(gòu)造確保值不會(huì)更改。
- 可發(fā)現(xiàn)性:IDE可以建議
PhoneNumber
,SSN
等,使API易於正確使用。 - 一致性:所有實(shí)例都遵循相同的規(guī)則(格式化,歸一化等)。
您還可以添加幫助者:
public bool iscorporate()=> value.endswith(“@company.com”,stringcomparison.ordinalignorecase);
常見模式和優(yōu)化
在創(chuàng)建每個(gè)字符串的新類型的同時(shí),現(xiàn)代語(yǔ)言減少了開銷:
- C#記錄免費(fèi)提供
Equals
GetHashCode
和不變性。 - 隱式/顯式操作員(少見)可以輕鬆互動(dòng):
公共靜態(tài)隱式操作員字符串(emailAddress email)=> email.value;
但是要謹(jǐn)慎 - 如果過(guò)度使用,隱性轉(zhuǎn)換可以帶回原始問(wèn)題。
或者,僅在需要時(shí)暴露.Value
(例如,用於序列化),使域模型嚴(yán)格。
還考慮歸一化:
公共記錄用戶名(字符串值) { public用戶名():此(“ guest”){} public用戶名(字符串值):this(value?trim().tolowerInvariant()??“ guest”){} }
這確保了整個(gè)系統(tǒng)的一致格式。
框架和生態(tài)系統(tǒng)支持
現(xiàn)代ORM(例如EF Core)支持值轉(zhuǎn)換以將值對(duì)象映射到數(shù)據(jù)庫(kù)列:
ModelBuilder.entity <user>() .property(u => u.email) 。
還可以教授序列化庫(kù)(System.Text.json,Newtonsoft)通過(guò)轉(zhuǎn)換器處理這些類型。
借助源生成器或羅斯林分析儀,您甚至可以自動(dòng)生成的樣板(例如, NonEmptyString
基本類型)。
最後的想法
將特定於領(lǐng)域的字符串視為價(jià)值對(duì)像不僅學(xué)術(shù)的對(duì)象 - 它可以防止錯(cuò)誤,提高可維護(hù)性並使您的代碼明確意圖。
啟動(dòng)?。哼x擇一個(gè)關(guān)鍵字符串(例如Email
或PhoneNumber
),然後包裝。一旦看到了好處 - 更少的錯(cuò)誤,清晰的API,自我紀(jì)錄的代碼 - 您會(huì)想知道為什麼您不早點(diǎn)做。
這不是要消除字符串;這是關(guān)於給他們意義。
基本上,如果字符串代表您的域中的概念,則應(yīng)該得到類型。
以上是字符串作為價(jià)值對(duì)象:一種現(xiàn)代的特定領(lǐng)域字符串類型的方法的詳細(xì)內(nèi)容。更多資訊請(qǐng)關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

熱AI工具

Undress AI Tool
免費(fèi)脫衣圖片

Undresser.AI Undress
人工智慧驅(qū)動(dòng)的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費(fèi)的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費(fèi)的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強(qiáng)大的PHP整合開發(fā)環(huán)境

Dreamweaver CS6
視覺化網(wǎng)頁(yè)開發(fā)工具

SublimeText3 Mac版
神級(jí)程式碼編輯軟體(SublimeText3)

sprintf和vsprintf在PHP中提供高級(jí)字符串格式化功能,答案依次為:1.可通過(guò)%.2f控制浮點(diǎn)數(shù)精度、%d確保整數(shù)類型,並用d實(shí)現(xiàn)零填充;2.使用%1$s、%2$d等positional佔(zhàn)位符可固定變量位置,便於國(guó)際化;3.通過(guò)%-10s實(shí)現(xiàn)左對(duì)齊、]右對(duì)齊,適用於表格或日誌輸出;4.vsprintf支持?jǐn)?shù)組傳參,便於動(dòng)態(tài)生成SQL或消息模板;5.雖無(wú)原生命名佔(zhàn)位符,但可通過(guò)正則回調(diào)函數(shù)模擬{name}語(yǔ)法,或結(jié)合extract()使用關(guān)聯(lián)數(shù)組;6.應(yīng)通過(guò)substr_co

nullbytes(\ 0)cancauseunexpectedBehaviorInphpWhenInterfacingWithCextensOsSySycallsBecaUsectReats \ 0asastringTermInator,EventHoughPhpStringSareBinary-SaftringsareBinary-SafeanDeandSafeanDeandPresserve.2.infileperations.2.infileperations,filenamecontakecontakecontablescontakecontabternallikebybybytartslikeplikebybytrikeplinebybytrikeplike'''''''';

TodefendagainstXSSandinjectioninPHP:1.Alwaysescapeoutputusinghtmlspecialchars()forHTML,json_encode()forJavaScript,andurlencode()forURLs,dependingoncontext.2.Validateandsanitizeinputearlyusingfilter_var()withappropriatefilters,applywhitelistvalidation

PHP的PCRE函數(shù)支持高級(jí)正則功能,1.使用捕獲組()和非捕獲組(?:)分離匹配內(nèi)容並提升性能;2.利用正/負(fù)向先行斷言(?=)和(?!))及後發(fā)斷言(?

PHP的原生序列化比JSON更適合PHP內(nèi)部數(shù)據(jù)存儲(chǔ)與傳輸,1.因?yàn)樗鼙A敉暾麛?shù)據(jù)類型(如int、float、bool等);2.支持私有和受保護(hù)的對(duì)象屬性;3.可安全處理遞歸引用;4.反序列化時(shí)無(wú)需手動(dòng)類型轉(zhuǎn)換;5.在性能上通常優(yōu)於JSON;但不應(yīng)在跨語(yǔ)言場(chǎng)景使用,且絕不能對(duì)不可信輸入調(diào)用unserialize(),以免引發(fā)遠(yuǎn)程代碼執(zhí)行攻擊,推薦在僅限PHP環(huán)境且需高保真數(shù)據(jù)時(shí)使用。

角色級(jí)別的manipulationCanseverelyImpactperformanceInimmutable-stranguagesDuetorePeatEdeDallocations andCoppy; 1)避免使用repeatePeatedConcatenation = InvolyOps,而不是usemutablebufferslikelist''.join()inpythonorstringbuilderdringbuilderdercerinjava; 2)minimizizizizizin; 2)

Processlargefilesline-by-lineorinchunksusingfgets()orfread()insteadofloadingentirefilesintomemorywithfile()orfile_get_contents().2.Minimizeunnecessarystringcopiesbyavoidingchainedstringfunctions,breakingdownoperations,andusingunset()onlargestringswhe

PHP的pack()和unpack()函數(shù)用於在PHP變量與二進(jìn)制數(shù)據(jù)之間轉(zhuǎn)換。 1.pack()將變量如整數(shù)、字符串打包成二進(jìn)制數(shù)據(jù),unpack()則將二進(jìn)制數(shù)據(jù)解包為PHP變量,二者均依賴格式字符串指定轉(zhuǎn)換規(guī)則。 2.常見格式碼包括C/c(8位有/無(wú)符號(hào)字符)、S/s(16位短整型)、L/l/V/N(32位長(zhǎng)整型,分別對(duì)應(yīng)不同字節(jié)序)、f/d(浮點(diǎn)/雙精度)、a/A(填充字符串)、x(空字節(jié))等。 3.字節(jié)序至關(guān)重要:V表示小端序(Intel),N表示大端序(網(wǎng)絡(luò)標(biāo)準(zhǔn)),跨平臺(tái)通信時(shí)應(yīng)優(yōu)先使用V
