ใช้คลาสสาธารณะที่ซ้อนกันเพื่อจัดระเบียบค่าคงที่


21

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

public static final String CREDITCARD_ACTION_SUBMITDATA = "6767";
public static final String CREDITCARD_UIFIELDID_CARDHOLDER_NAME = "3959854";
public static final String CREDITCARD_UIFIELDID_EXPIRY_MONTH = "3524";
public static final String CREDITCARD_UIFIELDID_ACCOUNT_ID = "3524";
...
public static final String BANKPAYMENT_UIFIELDID_ACCOUNT_ID = "9987";

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

public class IntegrationSystemConstants
{
    public class CreditCard
    {
        public static final String UI_EXPIRY_MONTH = "3524";
        public static final String UI_ACCOUNT_ID = "3524";
        ...
    }
    public class BankAccount
    {
        public static final String UI_ACCOUNT_ID = "9987";
        ...
    }
}

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


1
ฉันชอบความคิดมากกว่า ฉันพบว่าตัวเองกำลังทำสิ่งที่คล้ายกันใน C ++ เมื่อฉันต้องการกำหนดขอบเขตและพฤติกรรมของ Enum คล้ายกับ C # แต่มีค่าที่มีความหมาย (ฉันคิดว่าความคิดดังกล่าวเกิดขึ้นเพราะฉันเคยชินกับการใช้คลาส Case จริงอยู่นี่เป็นโครงการส่วนตัวเพื่อความสนุกสนานไม่ใช่ความพยายามของทีม
KChaloux

คำตอบ:


13

ฉันไม่เห็นด้วยกับข้อเสนอสองข้อ

ค่าคงที่ควรจะอยู่ในพวกเขาเรียนที่เกี่ยวข้อง , ไม่ได้อยู่ในระดับคงที่ทั้งหมดในทั้งสองรูปแบบที่นำเสนอ

ไม่ควรมีคลาส / อินเตอร์เฟสคงที่เท่านั้น

ควรมีคลาสCreditCard(ไม่ใช่คลาสภายใน) ชั้นนี้ / อินเตอร์เฟซที่มีวิธีการเทียบกับบัตรเครดิตเช่นเดียวกับการคงที่และUI_EXPIRY_MONTHUI_ACCOUNT_ID

ควรมีคลาส / อินเตอร์เฟสBankAccount(ไม่ใช่คลาสภายใน) ชั้นนี้ / UI_ACCOUNT_IDอินเตอร์เฟซที่มีวิธีการเทียบกับบัญชีเงินฝากธนาคารเช่นเดียวกับการคง

ตัวอย่างเช่นใน Java API ทุกคลาส / อินเตอร์เฟสมีค่าคงที่ พวกเขาไม่ได้อยู่ในค่าคงที่คลาส / อินเทอร์เฟซที่มีค่าคงที่หลายร้อยไม่ว่าจะจัดกลุ่มเป็นชั้นในหรือไม่

ตัวอย่างเช่นค่าคงที่เหล่านี้เกี่ยวข้องกับชุดผลลัพธ์อยู่ในอินเตอร์เฟสResultSet:

static int  CLOSE_CURSORS_AT_COMMIT 
static int  CONCUR_READ_ONLY 
static int  CONCUR_UPDATABLE 
static int  FETCH_FORWARD 
static int  FETCH_REVERSE 
static int  FETCH_UNKNOWN 
static int  HOLD_CURSORS_OVER_COMMIT 
static int  TYPE_FORWARD_ONLY 
static int  TYPE_SCROLL_INSENSITIVE 
static int  TYPE_SCROLL_SENSITIVE 

อินเทอร์เฟซนี้มีลายเซ็นวิธีการที่สัมพันธ์กับชุดผลลัพธ์ พวกเขาไม่เพียงผู้ถือคงที่

ค่าคงที่เหล่านี้เกี่ยวข้องกับการกระทำของ UI อยู่ในอินเทอร์เฟซjavax.swing.Action:

static String   ACCELERATOR_KEY 
static String   ACTION_COMMAND_KEY 
static String   DEFAULT 
static String   LONG_DESCRIPTION 
static String   MNEMONIC_KEY 
static String   NAME 
static String   SHORT_DESCRIPTION 
static String   SMALL_ICON 

การใช้คลาสนั้นมีพฤติกรรมที่สัมพันธ์กับการกระทำของ UI พวกมันไม่ได้เป็นผู้ถือที่แน่นอน

ฉันรู้ว่า "ค่าคงที่" อย่างน้อยหนึ่งอินเทอร์เฟซ ( SwingConstants) โดยไม่มีวิธีการ แต่ไม่มีค่าคงที่หลายร้อยเพียงไม่กี่และทั้งหมดเกี่ยวข้องกับทิศทางและตำแหน่งขององค์ประกอบ UI:

static int  BOTTOM 
static int  CENTER 
static int  EAST 
static int  HORIZONTAL 
static int  LEADING 
static int  LEFT 
static int  NEXT 
static int  NORTH 
static int  NORTH_EAST 
static int  NORTH_WEST 
static int  PREVIOUS 
static int  RIGHT 
static int  SOUTH 
static int  SOUTH_EAST 
static int  SOUTH_WEST 
static int  TOP 
static int  TRAILING 
static int  VERTICAL 
static int  WEST 

ฉันคิดว่าค่าคงที่คลาสเท่านั้นไม่ใช่การออกแบบ OO ที่ดี


1
ในขณะที่ฉันยอมรับว่าค่าคงที่คลาสเท่านั้นส่วนใหญ่แล้วเป็นสัญญาณของการออกแบบที่ไม่ดี แต่ก็มีการใช้งานที่ถูกกฎหมาย ตัวอย่างเช่นค่าคงที่ไม่ "เสมอ" กับคลาสที่ต้องการ Keys for Intent Extras ในการเขียนโปรแกรม Android เป็นหนึ่งในตัวอย่างที่เป็นรูปธรรมเช่นนี้
curioustechizen

1
+1 แต่ค่าคงที่ UI อาจไม่ควรอยู่ในรูปแบบธุรกิจเช่น BankAccount พวกมันอยู่ในคลาส UI บางตัว
วินไคลน์

10

มันเกิดขึ้นว่าค่าคงที่กระจัดกระจายเกินไปและควรจัดเป็นไฟล์ค่าคงที่ "มาสเตอร์" ไฟล์เดียว

นี่เป็นวิธีแก้ปัญหาที่ผิด 100%ของค่าคงที่ที่ "หายาก" มันเป็นข้อผิดพลาดพื้นฐาน (น่าเสียดายที่ผู้เขียนโปรแกรมทั้งหมดมักทำผิดพลาด) ในการจัดกลุ่มสิ่งต่าง ๆ ตามเกณฑ์ทางเทคนิคเช่นค่าคงที่ค่าคงที่หรืออินเทอร์เฟซ

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

นอกจากนี้ไฟล์ค่าคงที่ขนาดใหญ่หนึ่งไฟล์ยังคงฆ่าความเร็วการพัฒนาใน Javaเนื่องจากค่าคงที่จะถูกแทรกเข้าไปในคลาสที่ใช้ในเวลาคอมไพล์ดังนั้นการเปลี่ยนแปลงใด ๆ จะบังคับให้คอมไพล์ไฟล์เหล่านั้นทั้งหมดใหม่อีกครั้ง หากคุณมีหนึ่งไฟล์ที่มีค่าคงที่ที่ใช้ทุกที่ส่วนใหญ่คุณจะสูญเสียผลประโยชน์จากการรวบรวมแบบเพิ่มขึ้น: เฝ้าดู Eclipse ล็อคเป็นเวลา 15 นาทีเมื่อคอมไพล์คอมไพล์โครงการของคุณใหม่สำหรับการเปลี่ยนแปลงทุกไฟล์ และเนื่องจากไฟล์นั้นมีค่าคงที่ทั้งหมดที่ใช้งานได้ทุกที่คุณจะต้องเปลี่ยนบ่อยๆ ใช่ฉันกำลังพูดจากประสบการณ์ส่วนตัว


ฉันไม่ได้ตระหนักถึงผลกระทบที่อาจเกิดขึ้นกับสภาพแวดล้อมการพัฒนาและฉันเดาว่าวิธีการเรียนที่ซ้อนกันจะไม่ช่วยอะไรได้มากใช่มั้ย
FrustratedWithFormsDesigner

1
@FrustratedWithFormsDesigner: มันขึ้นอยู่กับความพยายามเท่าไหร่ที่กลไกการรวบรวมที่เพิ่มขึ้นใช้เวลากับการพึ่งพาแบบจำลอง
Michael Borgwardt

9

คุณพูดถูก คำแนะนำของคุณอนุญาตให้โปรแกรมเมอร์เขียนimport static Constants.BankAccount.*และกำจัดการซ้ำซ้อนของ 'BANKACCOUNT_' ซ้ำ ๆ การต่อเรียงข้อมูลเป็นทางเลือกที่ไม่ดีสำหรับการกำหนดขอบเขตที่แท้จริง ที่กล่าวว่าฉันไม่ได้หวังมากสำหรับคุณที่จะเปลี่ยนวัฒนธรรมของทีม พวกเขามีแนวปฏิบัติที่เหมาะสมและไม่น่าจะเปลี่ยนแปลงแม้ว่าคุณจะแสดงผู้เชี่ยวชาญ 100 คนที่กล่าวว่าพวกเขาผิด

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


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

8
คลาสค่าคงที่ที่เปลี่ยนแปลงตลอดเวลา ... มีบางสิ่งในเซนถ้าคุณขุดให้หนักพอ
KChaloux

2
@FrustratedWithFormsDesigner: UI-field IDs หรือไม่ ไม่ทราบว่าจะหาค่าได้ที่ไหน? ฟังดูเหมือนกองใหญ่ของ WTF คุณมีความเห็นอกเห็นใจของฉัน
วินไคลน์

6

ทั้งสองวิธีการทำงานและนั่นคือสิ่งที่สำคัญในตอนท้ายของวัน

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


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

1
@GoranJovic ทุกรูปแบบการต่อต้านมีประโยชน์ในทางใดทางหนึ่ง (หรืออย่างน้อยก็สะดวก) มันจะไม่กลายเป็นรูปแบบถ้ามันไม่ใช่
yannis

1

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

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

หากมีสิ่งใดข้อเสนอแนะของคุณจะช่วยไม่ให้เกิดการใช้ค่าคงที่ "ผิด" แม้ว่าอาจเหมาะสมในบางสถานการณ์ก็ตาม โดยการตัดค่าคงที่ภายในคลาสตัวแทนมันจะสนับสนุนให้นักพัฒนาคิดถึงถ้าพวกเขาควรจะใช้มัน ตัวอย่างเช่นถ้าฉันดึงCreditCard.SomeConstantเพื่อการใช้งานทั่วไปฉันควรสงสัยว่าทำไมไม่มีGeneral.SomeConstantในสถานการณ์นั้นแทน

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


1

ฉันทำสิ่งนี้เป็นครั้งคราว (ใน C #) โดยเฉพาะอย่างยิ่งถ้าฉันต้องการโปรแกรมต่อต้าน / แยกวิเคราะห์โครงสร้าง XML ที่รู้จักกันดีและคงที่หรือสิ่งที่ซ้อนกันและสตริงหนัก ... เช่นอินสแตนซ์ parser บล็อกการกำหนดค่าที่กำหนดเอง

ฉันสร้างโครงสร้างคลาสที่ซ้อนกันที่ตรงกับโครงสร้างลำดับชั้นของ XML ด้วยชื่อคลาสที่สอดคล้องกับองค์ประกอบที่มีสตริง "ElementName" คุณสมบัติ const และคุณสมบัติที่คล้ายกันที่สอดคล้องกับแต่ละแอตทริบิวต์ (ถ้ามี)

มันทำให้ง่ายต่อการตั้งโปรแกรมกับ Xml ที่เกี่ยวข้อง

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