มันเป็นกลิ่นรหัสหรือไม่ถ้าคุณมักจะสร้างวัตถุเพียงเพื่อเรียกวิธีการในมัน


14

ฉันได้รับรหัสฐานซึ่งมีรหัสจำนวนมากที่ไปในลักษณะนี้:

SomeDataAdapter sda = new SomeDataAdapter();
sda.UpdateData(DataTable updateData);

จากนั้น sda จะไม่ถูกใช้อีกครั้ง

เป็นกลิ่นรหัสที่บ่งชี้ว่าวิธีการเหล่านั้นควรเป็นวิธีการเรียนแบบคงที่แทน?


คลาสเหล่านี้ใช้อินเตอร์เฟสใด ๆ หรือไม่?
ซ้ำ

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

22
@ ไมค์: ทำไมคุณต้องเยาะเย้ยวิธีการคงที่? ฉันรู้สึกเบื่อหน่ายกับการโต้แย้งที่ผิดพลาดอย่างมากว่าวิธีการคงที่นั้นไม่สามารถทดสอบได้ หากวิธีการคงที่ของคุณถือสถานะหรือสร้างผลข้างเคียงนั่นคือความผิดของคุณไม่ใช่ความผิดของวิธีการทดสอบของคุณ
Robert Harvey

9
ในความคิดของฉันมันเป็นกลิ่นของภาษาที่แสดงให้เห็นจุดอ่อนของการวิเคราะห์ "ทุกอย่างต้องเป็นคลาส"
Ben

7
@RobertHarvey: คุณอาจต้องจำลองวิธีแบบคงที่ด้วยเหตุผลเดียวกับที่คุณจำลองวิธีอื่น ๆ : มันแพงเกินไปที่จะเรียกระหว่างการทดสอบหน่วย
kevin cline

คำตอบ:


1

ฉันจะพิจารณาว่ากลิ่นสถาปัตยกรรมใน UpdateData นั้นน่าจะเป็นของคลาส 'service'

ข้อมูลอยู่ที่ไหนของ Apple ตำแหน่งที่ AppleAdapter เป็นคลาสบริการ / ข่าวกรองธุรกิจ โดยที่ AppleService เป็นการอ้างอิง Singleton ไปยัง AppleAdapter ที่มีอยู่นอกเมธอดปัจจุบัน

private static volatile AppleAdapter _appleService = null;
private static object _appleServiceLock = new object();
private AppleAdapter AppleService
{
    get
    {
        if (_appleService == null)
        {
            lock (_appleServiceLock)
            {
                if (_appleService == null)
                    _appleService = new AppleAdapter();
            }
        }
        return _appleService;
    }
}

public SomeAppleRelatedMethod(Apple apple)
{
    AppleService.UpdateData(apple);
}

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

คุณรู้อะไรไหม? ถ้า SomeDataAdapter เป็น ADO IDbDataAdapter (ซึ่งเกือบจะแน่นอน), ไม่สนใจคำตอบทั้งหมดนี้!

: P

ฉันไม่ได้รับอนุญาตให้เพิ่มความคิดเห็นในคำถามเดิม แต่ถ้าคุณสามารถระบุได้ว่ามีรหัสนี้อยู่ที่ไหน

หากรหัสนี้แสดงถึงการนำไปใช้งานแบบกำหนดเองของ IDbDataAdapter และ UpdateData กำลังสร้าง IDbConnection, IDbCommand และเดินสายไปตามหลังฉากแล้วฉันไม่คิดเลยว่าจะมีกลิ่นรหัสเพราะตอนนี้เรากำลังพูดถึงสตรีมและอื่น ๆ สิ่งที่ต้องกำจัดเมื่อเราใช้งานเสร็จแล้ว


12
ช่วยด้วย! ฉันจมน้ำในรูปแบบซอฟต์แวร์
Robert Harvey

4
... หรือฉีดเป็นการพึ่งพา ;)
Rob

12
ล้อเล่นกับล็อคเดี่ยวและการตรวจสอบซ้ำเพื่อให้ได้สิ่งที่เทียบเท่ากับฟังก์ชั่น / ขั้นตอนง่าย ๆ คือรหัสที่ยิ่งใหญ่กว่าสำหรับฉัน!
Ben

3

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


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

1

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

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


นอกจากนี้ยังอาจหมายความว่าคุณต้องการให้วิธีการแบบคงที่เพื่อส่งกลับรุ่นที่แก้ไข (หรือสำเนาที่แก้ไข) ของวัตถุที่คุณส่งผ่านไป
Robert Harvey

2
"ถ้าคุณติดอยู่ในภาษาที่ไม่มีฟังก์ชั่นชั้นหนึ่ง": ไม่มีความแตกต่างระหว่างวัตถุที่มีเพียงวิธีเดียวและฟังก์ชั่นชั้นหนึ่ง (หรือปิดชั้นแรก): พวกเขาเป็นเพียงมุมมองที่แตกต่างกันสองของเดียวกัน สิ่ง.
Giorgio

4
@ จอร์โจในทางทฤษฎีไม่มี ในทางปฏิบัติหากภาษาของคุณไม่มีซินแท็กซ์น้ำตาลอย่างน้อยก็เป็นความแตกต่างระหว่างfn x => x + 1และnew Function<Integer, Integer>() { public Integer eval(Integer x) { return x + 1; }};หรือ จำกัด ตัวคุณเองกับฟังก์ชั่นที่ใช้รหัสยากและมีประโยชน์น้อย
Doval

ทำไมfn x => x + 1น้ำตาล syntactic ถึงnew Function<Integer, Integer>() { public Integer eval(Integer x) { return x + 1; }}ไม่ได้? โอเคบางทีคุณอาจหมายถึงว่ามีคนติดอยู่ในภาษาที่ไม่มีประโยคน้ำตาลแบบนี้
Giorgio

@Giorgio คุณจะต้องถาม Oracle (จริงอยู่ที่ว่าจะเปลี่ยนเป็น Java 8 ในที่สุด) โปรดทราบว่าคุณต้องมีซินแท็กซ์น้ำตาลมากกว่าที่จะเป็นประโยชน์จริง ๆ - คุณต้องการที่จะผ่านวิธีการประกาศล่วงหน้าด้วยชื่อ การแกงก็มีประโยชน์เช่นกัน ในบางจุดคุณต้องสงสัยว่ามันคุ้มค่าที่จะมีความสามารถเหล่านั้นแทนที่จะปฏิบัติหน้าที่ในฐานะพลเมืองคนแรก แต่ตอนนี้ฉันกำลังจะปิดหัวข้อ
Doval

0

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


0

กำหนด "บ่อยครั้ง" วิธีมักจะทำคุณ instantiate วัตถุ? มาก - อาจจะไม่?

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

หากสภาวะยุ่งเหยิง แต่คุณต้องเริ่มทำสิ่งอื่น ๆ ให้คงที่เพื่อทำให้สิ่งแรกคงที่จากนั้นคุณต้องถามว่าส่วนใดที่จำเป็นต้องคงที่และส่วนใดทำไม่ได้

ใช่มันเป็นกลิ่นรหัสเพียงเล็ก ๆ


0

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


0

กลิ่นนี่คือสิ่งนี้เป็นรหัสขั้นตอนห่อ (น้อยที่สุด) ในวัตถุ

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

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

ดังนั้นกลิ่นหลักของที่นี่คือผู้เขียนใช้คลาสบางทีอาจเป็นเพราะคอมไพเลอร์ต้องการ

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

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