โฟลเดอร์ในโซลูชันควรตรงกับเนมสเปซหรือไม่


129

โฟลเดอร์ในโซลูชันควรตรงกับเนมสเปซหรือไม่

ในโปรเจ็กต์ทีมหนึ่งของฉันเรามีไลบรารีคลาสที่มีโฟลเดอร์ย่อยมากมายในโปรเจ็กต์

ชื่อโครงการและเนมสเปซ: MyCompany.Project.Section.

ภายในโปรเจ็กต์นี้มีหลายโฟลเดอร์ที่ตรงกับส่วนเนมสเปซ:

  • โฟลเดอร์VehiclesมีคลาสในMyCompany.Project.Section.Vehiclesเนมสเปซ
  • โฟลเดอร์ClothingมีคลาสในMyCompany.Project.Section.Clothingเนมสเปซ
  • เป็นต้น

ภายในโปรเจ็กต์เดียวกันนี้เป็นอีกโฟลเดอร์โกง

  • โฟลเดอร์BusinessObjectsมีคลาสในMyCompany.Project.Sectionเนมสเปซ

มีบางกรณีเช่นนี้ที่สร้างโฟลเดอร์ขึ้นมาเพื่อ "ความสะดวกสบายขององค์กร"

คำถามของฉันคือมาตรฐานคืออะไร? ในไลบรารีคลาสโฟลเดอร์มักจะตรงกับโครงสร้างเนมสเปซหรือเป็นกระเป๋าแบบผสม?


9
หมายเหตุ: ReSharper จะบ่นหากเนมสเปซไม่ตรงกับลำดับชั้นของโฟลเดอร์
เฟรด

คำตอบ:


77

นอกจากนี้โปรดทราบว่าหากคุณใช้เทมเพลตในตัวเพื่อเพิ่มคลาสลงในโฟลเดอร์โดยค่าเริ่มต้นจะถูกใส่ไว้ในเนมสเปซที่สะท้อนถึงลำดับชั้นของโฟลเดอร์

ชั้นเรียนจะหาได้ง่ายขึ้นและเพียงอย่างเดียวควรมีเหตุผลที่ดีพอ

กฎที่เราปฏิบัติตามคือ:

  • ชื่อโปรเจ็กต์ / แอสเซมบลีเหมือนกับเนมสเปซรูทยกเว้นการสิ้นสุด. dll
  • ข้อยกเว้นเฉพาะของกฎข้างต้นคือโปรเจ็กต์ที่มีนามสกุล. Core,. Core จะถูกถอดออก
  • โฟลเดอร์เท่ากับเนมสเปซ
  • หนึ่งประเภทต่อไฟล์ (class, struct, enum, delegate ฯลฯ ) ช่วยให้ค้นหาไฟล์ที่ถูกต้องได้ง่าย

1
+1 สำหรับ"ข้อยกเว้นเพียงอย่างเดียวสำหรับกฎข้างต้นคือโครงการที่มีการลงท้ายด้วย. Core, .Core ถูกถอดออก"เพียงอย่างเดียว ฉันมีการชุมนุมและการเรียนทั้งหมดเริ่มต้นด้วยMyProject.Core.dll MyProject.Coreการตัด.Coreคำต่อท้ายออกไปมีความหมายมากขึ้น
Luiz Damim

2
ข้อยกเว้นอื่นที่ฉันอาจเพิ่มคือข้อยกเว้น มีข้อยกเว้นต่อท้ายด้วย 'Exception' อยู่แล้วดังนั้นเนมสเปซเพิ่มเติมจึงซ้ำซ้อน นอกจากนี้ยังอาจทำให้ยุ่งเหยิงเมื่อมีส่วนหนึ่งของเนมสเปซที่มีคำว่า Exception (อาจทำให้ System.Exception สับสน) อย่างไรก็ตามการจัดระเบียบลงในโฟลเดอร์นั้นมีประโยชน์มากทีเดียว
phillipwei

55

เลขที่

ฉันได้ลองใช้ทั้งสองวิธีในโครงการขนาดเล็กและขนาดใหญ่ทั้งแบบเดี่ยว (ฉัน) และทีมนักพัฒนา

ฉันพบว่าเส้นทางที่ง่ายและมีประสิทธิผลที่สุดคือการมีเนมสเปซเดียวต่อโปรเจ็กต์และทุกคลาสจะเข้าสู่เนมสเปซนั้น จากนั้นคุณมีอิสระที่จะใส่ไฟล์คลาสลงในโฟลเดอร์โปรเจ็กต์ที่คุณต้องการ ไม่มีความยุ่งยากในการเพิ่มโดยใช้คำสั่งที่ด้านบนของไฟล์ตลอดเวลาเนื่องจากมีเพียงเนมสเปซเดียว

สิ่งสำคัญคือต้องจัดระเบียบไฟล์ต้นฉบับลงในโฟลเดอร์และในความคิดของฉันนั่นคือทุกโฟลเดอร์ที่ควรใช้ การกำหนดให้โฟลเดอร์เหล่านี้แมปกับเนมสเปซนั้นไม่จำเป็นสร้างงานเพิ่มขึ้นและฉันพบว่าเป็นอันตรายต่อองค์กรเพราะภาระที่เพิ่มเข้ามากระตุ้นให้เกิดความระส่ำระสาย

ใช้คำเตือน FxCop นี้เช่น:

CA1020: หลีกเลี่ยงเนมสเปซที่มีไม่กี่ประเภท
สาเหตุ: เนมสเปซอื่นที่ไม่ใช่เนมสเปซส่วนกลางมีน้อยกว่าห้าประเภท https://msdn.microsoft.com/en-gb/library/ms182130.aspx

คำเตือนนี้กระตุ้นให้มีการทิ้งไฟล์ใหม่ลงใน Project ทั่วไปโฟลเดอร์ทั่วไปหรือแม้แต่รูทโปรเจ็กต์จนกว่าคุณจะมีคลาสที่คล้ายกันสี่คลาสเพื่อแสดงเหตุผลในการสร้างโฟลเดอร์ใหม่ จะเกิดขึ้นหรือไม่?

การค้นหาไฟล์

คำตอบที่ได้รับการยอมรับระบุว่า "ชั้นเรียนจะหาได้ง่ายขึ้นและเพียงอย่างเดียวก็ควรมีเหตุผลที่ดีพอ"

ฉันสงสัยว่าคำตอบหมายถึงการมีหลายเนมสเปซในโปรเจ็กต์ที่ไม่ได้แมปกับโครงสร้างโฟลเดอร์แทนที่จะเป็นสิ่งที่ฉันแนะนำซึ่งเป็นโปรเจ็กต์ที่มีเนมสเปซเดียว

ไม่ว่าในกรณีใดก็ตามในขณะที่คุณไม่สามารถระบุได้ว่าไฟล์คลาสอยู่ในโฟลเดอร์ใดจากเนมสเปซคุณสามารถค้นหาได้โดยใช้ Go To Definition หรือกล่องตัวสำรวจโซลูชันการค้นหาใน Visual Studio นี่ไม่ใช่ปัญหาใหญ่ในความคิดของฉัน ฉันไม่เสียเวลาในการพัฒนาแม้แต่ 0.1% ไปกับปัญหาในการค้นหาไฟล์เพื่อปรับแต่งให้เหมาะสม

ชื่อการปะทะกัน

การสร้างเนมสเปซหลายรายการทำให้โปรเจ็กต์มีสองคลาสที่มีชื่อเดียวกัน แต่นั่นเป็นสิ่งที่ดีจริงๆหรือ? อาจจะง่ายกว่าไหมที่จะไม่อนุญาตให้เป็นไปได้? การอนุญาตให้สองคลาสที่มีชื่อเดียวกันทำให้เกิดสถานการณ์ที่ซับซ้อนขึ้นโดยที่ 90% ของเวลาทำงานในลักษณะหนึ่งแล้วจู่ๆคุณก็พบว่าคุณมีกรณีพิเศษ สมมติว่าคุณมีคลาสสี่เหลี่ยมผืนผ้าสองคลาสที่กำหนดไว้ในเนมสเปซแยกกัน:

  • คลาส Project1 ภาพสี่เหลี่ยมผืนผ้า
  • คลาส Project1.Window.Rectangle

เป็นไปได้ที่จะประสบปัญหาที่ไฟล์ต้นฉบับต้องมีทั้งสองเนมสเปซ ตอนนี้คุณต้องเขียนเนมสเปซแบบเต็มทุกที่ในไฟล์นั้น:

var rectangle = new Project1.Window.Rectangle();

หรือยุ่งเกี่ยวกับการใช้คำสั่งที่น่ารังเกียจ:

using Rectangle = Project1.Window.Rectangle;

ด้วยเนมสเปซเดียวในโปรเจ็กต์ของคุณคุณจะถูกบังคับให้สร้างชื่อที่แตกต่างกันและฉันจะโต้แย้งชื่อที่สื่อความหมายมากกว่านี้:

  • คลาส Project1.ImageRectangle
  • คลาส Project1.WindowRectangle

และการใช้งานก็เหมือนกันทุกที่คุณไม่จำเป็นต้องจัดการกับกรณีพิเศษเมื่อไฟล์ใช้ทั้งสองประเภท

ใช้งบ

using Project1.General;  
using Project1.Image;  
using Project1.Window;  
using Project1.Window.Controls;  
using Project1.Shapes;  
using Project1.Input;  
using Project1.Data;  

VS

using Project1;

ความสะดวกที่ไม่ต้องเพิ่มเนมสเปซตลอดเวลาขณะเขียนโค้ด มันไม่ใช่เวลาที่ต้องใช้จริงๆมันคือการหยุดพักที่ต้องทำและเติมไฟล์ด้วยงบที่ใช้จำนวนมาก - เพื่ออะไร? คุ้มมั้ย?

การเปลี่ยนโครงสร้างโฟลเดอร์โครงการ

ถ้าโฟลเดอร์ถูกแมปกับเนมสเปซพา ธ โฟลเดอร์โปรเจ็กต์จะถูกฮาร์ดโค้ดลงในไฟล์ซอร์สแต่ละไฟล์อย่างมีประสิทธิภาพ ซึ่งหมายความว่าการเปลี่ยนชื่อหรือย้ายไฟล์หรือโฟลเดอร์ในโปรเจ็กต์จำเป็นต้องมีการเปลี่ยนแปลงเนื้อหาของไฟล์จริง ทั้งการประกาศเนมสเปซของไฟล์ในโฟลเดอร์นั้นและการใช้คำสั่งในไฟล์อื่น ๆ ทั้งหมดที่อ้างอิงคลาสในโฟลเดอร์นั้น แม้ว่าการเปลี่ยนแปลงจะเป็นเรื่องเล็กน้อยกับการใช้เครื่องมือ แต่ก็มักจะส่งผลให้มีการคอมมิตขนาดใหญ่ซึ่งประกอบด้วยไฟล์จำนวนมากที่คลาสไม่ได้เปลี่ยนแปลงด้วยซ้ำ

ด้วยเนมสเปซเดียวในโปรเจ็กต์คุณสามารถเปลี่ยนโครงสร้างโฟลเดอร์โปรเจ็กต์ได้ตามที่คุณต้องการโดยไม่ต้องแก้ไขไฟล์ต้นฉบับใด ๆ

Visual Studio จะแมปเนมสเปซของไฟล์ใหม่กับโฟลเดอร์โครงการที่สร้างขึ้นโดยอัตโนมัติ

โชคไม่ดี แต่ฉันพบว่าความยุ่งยากในการแก้ไขเนมสเปซนั้นน้อยกว่าความยุ่งยากในการจัดการกับพวกเขา นอกจากนี้ฉันยังมีนิสัยในการคัดลอกวางไฟล์ที่มีอยู่แทนที่จะใช้ Add-> New

Intellisense และ Object Browser

ประโยชน์ที่ใหญ่ที่สุดในความคิดของฉันในการใช้หลายเนมสเปซในโครงการขนาดใหญ่คือการมีองค์กรพิเศษเมื่อดูคลาสในเครื่องมือใด ๆ ที่แสดงคลาสในลำดับชั้นของเนมสเปซ แม้แต่เอกสาร เห็นได้ชัดว่าการมีเนมสเปซเดียวในโปรเจ็กต์ส่งผลให้คลาสทั้งหมดแสดงในรายการเดียวแทนที่จะแยกเป็นหมวดหมู่ อย่างไรก็ตามโดยส่วนตัวแล้วฉันไม่เคยนิ่งงันหรือล่าช้าเพราะขาดสิ่งนี้ดังนั้นฉันจึงไม่พบว่ามีประโยชน์มากพอที่จะปรับเนมสเปซหลายตัว

แต่ถ้าผมกำลังเขียนห้องสมุดชั้นสาธารณะขนาดใหญ่แล้วผมจะอาจจะใช้ namespaces ในหลายโครงการเพื่อให้มองการชุมนุมเรียบร้อยในการขับรถและเอกสาร


30
นี่เป็นหนึ่งในวิธีแก้ปัญหาฝันร้ายที่สุดที่ฉันเคยได้ยินมา หากคุณทำงานในโปรเจ็กต์ hello world ขนาดเล็กคำแนะนำนี้ใช้ได้ แต่ลองนึกดูว่าคุณมีไฟล์. cs มากกว่า 1,000 ไฟล์ มันจะทำให้เกิดปัญหามากมายไม่รู้จะเริ่มจากตรงไหน
BentOnCoding

10
"แต่สมมติว่าคุณมีไฟล์มากกว่า 1,000 .cs" ฉันเคยทำงานในโปรเจ็กต์ขนาดนั้นด้วยเนมสเปซเดียว ทุกอย่างปกติดี. คุณคิดว่าภัยพิบัติอะไรจะเกิดขึ้น?
Weyland Yutani

14
+1 สำหรับการคิด ฉันไม่คิดว่าฉันพร้อมที่จะลดเนมสเปซของฉันเหลือหนึ่งรายการต่อโปรเจ็กต์ แต่หลังจากทำงานกับเฟรมเวิร์กขนาดใหญ่ฉันกำลังสำรวจการลดจำนวนเนมสเปซเพื่อลดจำนวนการใช้คำสั่งและเพื่อช่วยในการค้นพบวิธีการขยาย ฉันคิดว่าคำตอบนี้ให้อาหารที่ดีสำหรับความคิด ขอบคุณ
Lee Gunn

3
@WeylandYutani ฉันรู้ว่าฉันมาสาย แต่ฉันต้องพูดถึงประโยคนี้ว่า: you can find it by using Go To Definition or the search solution explorer box in Visual Studioไม่จริงเสมอไป ลองใช้การถ่ายทอดทางพันธุกรรมและอินเทอร์เฟซมากมาย ... ขอให้โชคดีในการค้นหาไฟล์ที่ถูกต้อง
Emmanuel M.

11
นี่เป็นคำแนะนำที่ดีที่สุดชิ้นหนึ่งที่ฉันเคยเห็น เนมสเปซใช้สำหรับการแก้ปัญหาความขัดแย้งเท่านั้นไม่ได้จัดชั้นเรียน ใช้เนมสเปซเฉพาะในกรณีที่เหมาะสมที่จะใช้เช่นในกรณีที่คุณคาดว่าจะมีความขัดแย้งในการตั้งชื่อกับโปรเจ็กต์อื่น ๆ ที่อาจใช้โปรเจ็กต์ของคุณทำให้สามารถรวมเนมสเปซบางอย่างหรือไม่รวมกับการใช้คำสั่งได้ มันแย่มากที่ไม่มีโปรเจ็กต์ที่มีเนมสเปซ 3 หรือ 4 รายการขึ้นไปที่ถูกใช้บ่อย ๆ เพราะมันมักจะส่งผลให้คุณต้องเพิ่มและเพิ่มและเพิ่มและเพิ่ม แยกโครงการของคุณออกจากกัน
Triynko

31

ฉันคิดว่ามาตรฐานภายใน. NET คือการพยายามทำเมื่อเป็นไปได้ แต่อย่าสร้างโครงสร้างที่ลึกโดยไม่จำเป็นเพียงเพื่อยึดเป็นกฎที่ยาก โครงการของฉันไม่เป็นไปตามเนมสเปซ == โครงสร้างกฎ 100% ของเวลาบางครั้งมันก็สะอาด / ดีกว่าที่จะแยกออกจากกฎดังกล่าว

ใน Java คุณไม่มีทางเลือก ฉันจะเรียกมันว่ากรณีคลาสสิกของสิ่งที่ใช้ได้ผลในทางทฤษฎีเทียบกับสิ่งที่ได้ผล


1
ฉันจะบอกว่า "ทำเมื่อคุณต้องการให้บางสิ่งอยู่ในเนมสเปซของตัวเอง" ควรเป็นการตัดสินใจอย่างมีสติ หากโปรเจ็กต์ของคุณถูกแยกอย่างถูกต้องควรเป็นหนึ่งเนมสเปซต่อโปรเจ็กต์ ถ้าชั้นเรียนของคุณอยู่ในเนมสเปซควรอยู่ในโฟลเดอร์ที่มีเนมสเปซนั้นหรือตำแหน่งโฟลเดอร์ย่อยที่อย่างน้อยเฉพาะเจาะจงเท่ากับเนมสเปซ คลาสเช่น Car.Ford.Fusion (ถ้า Car.Ford เป็นเนมสเปซเดียวของคุณ) ควรอยู่ในโฟลเดอร์เช่น Car / Ford หรือลึกกว่านั้นเช่น Car / Ford / Sedans เช่นอย่างน้อยโฟลเดอร์ก็มีความเฉพาะเจาะจงเท่ากับเนมสเปซ อย่าใส่ไว้ในรถ / ไม่เกี่ยว / ฟอร์ด; ที่สับสน
Triynko

25

@lassevk: ฉันเห็นด้วยกับกฎเหล่านี้และมีอีกอย่างที่จะเพิ่ม

เมื่อฉันมีชั้นเรียนที่ซ้อนกันฉันยังคงแยกออกหนึ่งชั้นต่อไฟล์ แบบนี้:

// ----- Foo.cs
partial class Foo
{
    // Foo implementation here
}

และ

// ----- Foo.Bar.cs
partial class Foo
{
    class Bar
    {
        // Foo.Bar implementation here
    }
}

5

ฉันจะตอบว่าใช่

ขั้นแรกจะง่ายกว่าในการค้นหาไฟล์โค้ดจริงโดยตามลงไปที่เนมสเปซ (เช่นเมื่อมีคนส่งอีเมลถึงคุณโดยมีการเรียกใช้สแต็กข้อยกเว้นเปล่า) หากคุณปล่อยให้โฟลเดอร์ของคุณไม่ซิงค์กับเนมสเปซการค้นหาไฟล์ในโค้ดเบสขนาดใหญ่จะน่าเบื่อหน่าย

ประการที่สอง VS จะสร้างคลาสใหม่ที่คุณสร้างขึ้นในโฟลเดอร์ที่มีเนมสเปซเดียวกันกับโครงสร้างโฟลเดอร์หลัก หากคุณตัดสินใจที่จะต่อต้านสิ่งนี้มันจะเป็นเพียงงานประปาอีกหนึ่งงานที่ต้องทำทุกวันเมื่อเพิ่มไฟล์ใหม่

แน่นอนว่าสิ่งนี้ดำเนินไปโดยไม่ได้บอกว่าควรระมัดระวังเกี่ยวกับความลึกของลำดับชั้นของโฟลเดอร์ / เนมสเปซ xis



2

มาตรฐานคืออะไร?

ไม่มีมาตรฐานอย่างเป็นทางการ แต่ตามปกติแล้วรูปแบบการแมปโฟลเดอร์กับเนมสเปซถูกใช้กันอย่างแพร่หลายมากที่สุด

ในไลบรารีคลาสโฟลเดอร์มักจะตรงกับโครงสร้างเนมสเปซหรือเป็นกระเป๋าแบบผสม?

ใช่ในไลบรารีคลาสส่วนใหญ่โฟลเดอร์จะตรงกับเนมสเปซเพื่อความสะดวกในการจัดองค์กร

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.