Folder-by-type หรือ Folder-by-feature


59

ฉันใช้ประโยชน์จากคู่มือสไตล์ AngularJS ภายในคู่มือนี้มีรูปแบบที่เรียกว่าfolder-by-featureแทนที่จะเป็นfolder-by-typeและฉันอยากรู้จริง ๆ แล้วว่าอะไรคือวิธีที่ดีที่สุด (ในตัวอย่างนี้สำหรับ Java)

สมมติว่าฉันมีแอปพลิเคชันที่ฉันสามารถดึงผู้ใช้และสัตว์เลี้ยงโดยใช้บริการตัวควบคุมที่เก็บและวัตถุโดเมนของหลักสูตร

ด้วยรูปแบบโฟลเดอร์โดย -..... เรามีสองตัวเลือกสำหรับโครงสร้างบรรจุภัณฑ์ของเรา:

1. โฟลเดอร์ตามประเภท

com.example
├── domain
│    ├── User.java
│    └── Pet.java
├── controllers
│    ├── UserController.java
│    └── PetController.java
├── repositories
│    ├── UserRepository.java
│    └── PetRepository.java
├── services
│    ├── UserService.java
│    └── PetService.java
│   // and everything else in the project
└── MyApplication.java

2. คุณสมบัติแบบโฟลเดอร์

com.example
├── pet
│    ├── Pet.java
│    ├── PetController.java
│    ├── PetRepository.java
│    └── PetService.java
├── user
│    ├── User.java
│    ├── UserController.java
│    ├── UserRepository.java
│    └── UserService.java
│   // and everything else in the project
└── MyApplication.java

อะไรจะเป็นวิธีการที่ดีและอะไรคือข้อโต้แย้งที่จะทำเช่นนั้น?



1
ฉันไม่รู้ @Laiv ภาษา / กรอบงานมีผลกระทบกับคำตอบจริง ๆ หรือไม่? โดยไม่คำนึงถึงคำถามอื่น ๆ ที่เกี่ยวข้องอย่างแน่นอน
RubberDuck

1
จากนั้นฉันต้องแก้ไขคำตอบของฉัน และใช่มันเป็นไปได้ที่ซ้ำกัน
Laiv

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

2
ดูเหมือนว่าไม่มีใครพูดถึงแพ็คเกจใน Java ไม่ใช่แค่โฟลเดอร์ พวกเขายังส่งผลกระทบต่อการเข้าถึงสำหรับชั้นเรียนที่มีอยู่ ด้วยเหตุผลนี้ package-by-layer / type สามารถให้ค่า semantic ใน Java ได้
แองกัสช่างทอง

คำตอบ:


69

Folder-by-type ใช้งานได้กับโครงการขนาดเล็กเท่านั้น คุณสมบัติแบบโฟลเดอร์เป็นส่วนใหญ่ในกรณีส่วนใหญ่

Folder-by-type นั้นใช้ได้เมื่อคุณมีไฟล์จำนวนเล็กน้อยเท่านั้น (น้อยกว่า 10 ต่อประเภทจะบอกว่า) ทันทีที่คุณได้รับองค์ประกอบหลายรายการในโครงการของคุณทั้งหมดที่มีไฟล์หลาย ๆ ประเภทเดียวกันจะยากมากที่จะหาไฟล์จริงที่คุณกำลังมองหา

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

ก่อนอื่นคุณสามารถปฏิบัติตามข้อกำหนดการตั้งชื่อทั่วไปที่บอกประเภทของชื่อไฟล์ได้ ตัวอย่างเช่นคู่มือสไตล์ AngularJSยอดนิยมของ John Papa มีดังต่อไปนี้:

แนวทางการตั้งชื่อ

  • ใช้ชื่อที่สอดคล้องกันสำหรับส่วนประกอบทั้งหมดตามรูปแบบที่อธิบายคุณสมบัติของส่วนประกอบแล้ว (เป็นทางเลือก) ชนิดของส่วนประกอบ
    รูปแบบที่ฉันแนะนำคือ feature.type.js มี 2 ​​ชื่อสำหรับ
    เนื้อหาส่วนใหญ่:

    • ชื่อไฟล์ (avengers.controller.js)
    • ชื่อส่วนประกอบที่ลงทะเบียนกับ Angular (AvengersController)

ประการที่สองคุณสามารถรวมรูปแบบโฟลเดอร์ตามชนิดและคุณลักษณะต่อโฟลเดอร์เป็นแบบโฟลเดอร์ต่อคุณสมบัติ:

com.example
├── pet
|   ├── Controllers
│   |   ├── PetController1.java
|   |   └── PetController2.java
|   └── Services
│       ├── PetService1.java
│       └── PetService2.java
├── user
|   ├── Controllers
│   |   ├── UserController1.java
│   |   └── UserController2.java
|   └── Services
│       ├── UserService1.java
│       └── UserService2.java

1
คู่มือสไตล์ johnpapa นั้นตรงกับที่ฉันพูดถึง :-)
Jelle

1
บางครั้ง (บ่อยกว่าที่เราคิด) เราเพิ่มความซับซ้อนเกินไปให้กับสิ่งต่าง ๆ ที่ควรจะง่าย การตั้งชื่อและบรรจุภัณฑ์เป็นสิ่งเหล่านี้ คำแนะนำที่ดีที่สุดคือทำให้มันง่าย การผสมทั้งสองมีข้อดีและข้อเสียของวิธีทั้งสอง
Laiv

1
@Laiv ในตัวอย่างที่ฉันให้ฉันเห็นด้วย overkill ของมัน แต่ในกรณีธุรกิจจริงของฉันที่แต่ละโฟลเดอร์ประเภทสามารถมี 10-20 ไฟล์ได้อย่างง่ายดายฉันคิดว่ามันมีประโยชน์มากเพราะฟีเจอร์โฟลเดอร์โดยรวมจะเรียงตามลำดับ 50 ไฟล์อื่น
Reinstate Monica

6
fakking ขอบคุณ iPhone แก้ไขอัตโนมัติ! ฉันหมายถึง 'การพูดคุย'
Jelle

2
@Chaotic ตัวอย่างนี้เล็กน้อยเกินกว่าที่จะเริ่มพูดเจาะจงได้ แต่ในกรณีที่คุณมีชิ้นส่วนที่ใช้ข้ามองค์ประกอบหลายส่วนคุณควรเป็นส่วนประกอบของตัวเองที่ส่วนประกอบอื่น ๆ พึ่งพา
Reinstate Monica

26

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

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


10
ฉันจะเพิ่มที่ในโฟลเดอร์โดยคุณสมบัติทำให้ง่ายต่อการเล่นกับคลาสและขอบเขตวิธี (การป้องกันแพคเกจ ... )
Laiv

สำหรับโครงการขนาดเล็กคุณอาจมีเพียงฟีเจอร์เดียวเท่านั้น การจัดระเบียบตามประเภทในสถานการณ์นั้นง่ายกว่ามาก
aaaaaa

ยกตัวอย่างเช่นGrailsบังคับให้โฟลเดอร์แยกตามประเภทสำหรับโดเมน, ตัวควบคุม, บริการและอื่น ๆ ของคุณ
tylerwal

17

การทำงานกับแพคเกจโดยคุณลักษณะที่ยืนออกในต้นแบบสูงและการทำงานร่วมกัน มันช่วยให้เราสามารถเล่นกับขอบเขตของส่วนประกอบ ตัวอย่างเช่นเราสามารถใช้ตัวดัดแปลงการเข้าถึงเพื่อบังคับใช้LoDและการผกผันของการพึ่งพาสำหรับการรวมหรือ / และส่วนขยาย

เหตุผลอื่นคือ:

  • การนำรหัสที่ง่ายขึ้น
  • ระดับที่สูงขึ้นของสิ่งที่เป็นนามธรรม
  • ย่อขอบเขตให้น้อยที่สุด (บริบทที่ จำกัด ขอบเขต)
  • การทำให้เป็นโมดูลแนวตั้ง

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

ในที่สุดก็มีตัวเลือกที่ 3 " Package by component " ซึ่งในคำพูดของลุง Bob ดูเหมือนจะสอดคล้องกับหลักการของแพ็คเกจของเขามากขึ้น หากความเห็นบ๊อบของลุงสำคัญหรือไม่ฉันจะปล่อยให้คุณตัดสินใจ ฉันพบว่ามันน่าสนใจเนื่องจากการประชุมนี้สอดคล้องกับ Clean Architecture ของเขาซึ่งฉันชอบ

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