คือการใช้ *** Helper หรือ *** ใช้ประโยชน์จากคลาสที่มีเพียงวิธีคงที่ AntiPattern


19

ฉันมักจะเผชิญหน้ากับผู้ช่วยหรือใช้คลาสใน Java หรือภาษาอะไรก็ได้ ดังนั้นฉันจึงถามตัวเองว่านี่เป็น Anti Pattern หรือไม่และการมีอยู่ของคลาสเหล่านี้เป็นเพียงการขาดการออกแบบและสถาปัตยกรรมของซอฟต์แวร์

บ่อยครั้งที่คลาสเหล่านี้ถูก จำกัด ด้วยวิธีการคงที่ซึ่งทำสิ่งต่างๆมากมาย แต่ส่วนใหญ่มันแน่นอนขึ้นอยู่กับบริบทและรัฐเต็ม

คำถามของฉันคืออะไรความคิดเห็นของคุณเกี่ยวกับประเภทของผู้ช่วยคงที่ / ใช้ประโยชน์เช่นชั้นเรียนเพราะข้อได้เปรียบแน่นอนว่าการร้องขออย่างรวดเร็วโดยใช้เพียงชื่อชั้นเรียน

แล้วคุณจะหลีกเลี่ยงการใช้คลาสประเภทนี้ในระดับใด

ในความคิดของฉันคำหลัก "คงที่" ควรได้รับอนุญาตภายในการประกาศของคลาส (Java) และไม่ได้สำหรับวิธีการ ในความคิดของฉันคือการใช้วิธีนี้อาจเป็นทางเลือกที่ดีและตรงกลางเพื่อให้สามารถรวม Procuedural- และ OO-Paradigms ใน Java และหลีกเลี่ยงการใช้คำหลักที่ผิดพลาด

เพิ่มเติมเนื่องจากคำตอบ:

ตอนแรกฉันคิดว่ามันถูกกฎหมายอย่างสมบูรณ์เพื่อให้สามารถรวมกระบวนทัศน์ที่แตกต่างกันและแม้กระทั่งใช้ภาษาสคริปต์ตีความตีความรันไทม์ภายในเครื่องหรือรหัสที่รวบรวม vm

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

ฉันคิดว่าstaticควรถูกลบออกจาก Java โดยเฉพาะอย่างยิ่งตอนนี้ที่เป็นไปได้ที่จะใช้องค์ประกอบภาษาที่ซับซ้อนยิ่งขึ้น



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

ไม่เป็นไรถ้าคุณอ้างว่าทำโปรแกรมขั้นตอน ไม่ใช่ถ้าคุณอ้างว่าทำโปรแกรม (- เน้น) การเขียนโปรแกรม
เห็น

1
@Spotted: และเนื่องจากไม่มีคุณค่าทางธุรกิจในการอ้างสิทธิ์ว่าคุณเขียนโปรแกรมเชิงวัตถุเพียงอย่างเดียวคุณมักจะเขียนโปรแกรมกระบวนทัศน์แบบผสมและทำเรื่องอึ
RemcoGerlich

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

คำตอบ:


20

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

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

แน่นอนว่าการใช้ฟังก์ชั่น free / static นั้นไม่ได้ช่วยลดอันตรายของการแชร์แบบไม่แน่นอนโดยเฉพาะอย่างยิ่งสถานะระดับโลก


2
@ TimothyTruckle ไม่ว่าจะเป็นแบบคงที่หรือมีความฟุ่มเฟือยthisและต้องการบางสิ่งบางอย่างที่เหมาะสม
Caleth

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

5
@ TimothyTruckle แน่นอนว่าการดูแลรักษาสถานะนั้นจะเป็นเหตุผลสำคัญที่ทำให้ "ไม่ดี"
nvoigt

2
@nvoigt ฉันรู้สึกว่าคำตอบนี้จะได้รับการปรับปรุงอย่างมากโดยการระบุจุดนั้นอย่างชัดเจน สถิตยศาสตร์ไม่ดี; คนไร้สัญชาตินั้นดี ค่อนข้างง่ายจริงๆ
David Arno

3
@ TimothyTruckle นั่นไม่ใช่การแต่งงานที่แน่นหนา คุณกำลังอธิบายข้อต่อหลวม การมีเพศสัมพันธ์อย่างแน่นหนาในบริบทนี้จะหมายถึงการพึ่งพาระหว่างกัน การอ้างอิงแบบทางเดียวไม่เป็นไปตามข้อกำหนดนั้น
JimmyJames

18

ฟังก์ชั่นยูทิลิตี้คงที่หรือฟังก์ชั่นผู้ช่วยไม่ได้เป็นรูปแบบการต่อต้านถ้าพวกเขาปฏิบัติตามแนวทางบางอย่าง:

  1. ควรปราศจากผลข้างเคียง

  2. พวกเขาจะใช้สำหรับพฤติกรรมที่เฉพาะเจาะจงของโปรแกรมประยุกต์ที่ไม่ได้อยู่ในชั้นเรียนหรือชั้นเรียนที่ฟังก์ชั่นเหล่านี้ทำงาน

  3. พวกเขาไม่ต้องการสถานะใด ๆ ที่ใช้ร่วมกัน

กรณีการใช้งานทั่วไป:

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

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

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

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


4

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

ด้วยความคิดนี้จะมีวิธีการยูทิลิตี้มากมายในชั้นเรียนของผู้ปฏิบัติงานที่สามารถเครียดกันเป็นวิธีการคงที่ พวกเขาจะถูกป้อน / ใช้ใกล้กับวัตถุธรรมดาที่เก็บข้อมูลและส่งผ่าน

มันเป็นวิธีการที่ถูกต้องและสามารถทำงานได้ดีโดยเฉพาะอย่างยิ่งในระดับ


"สามารถทำงานได้ดีมากโดยเฉพาะอย่างยิ่งในระดับ"ไม่สาเหตุการมีเพศสัมพันธ์อย่างแน่นหนาจากการเข้าถึงแบบสแตติกจะมาถึงในไม่ช้าเมื่อโครงการเติบโตขึ้น
ทิโมธี Truckle

@TimothyTruckle คุณช่วยอธิบายได้ไหมว่า Agent.Save (obj) นั้นแน่นแฟ้นยิ่งกว่า Obj.Save () มากแค่ไหน? Agent มีความสามารถในการรับการอ้างอิง DI / IoC แม้สำหรับวิธีการแบบคงที่เช่นอินสแตนซ์ของคลาส สำหรับการอ้างอิง Stack Exchange นั้นเขียนขึ้นในความคิดประเภทนี้และปรับขนาดได้ดีกว่าแอพ ASP.Net อื่น ๆ ที่มีทรัพยากรน้อยกว่าแอพอื่นที่ฉันรู้จัก
Tracker1

"คุณช่วยอธิบายได้ไหมว่า Agent.Save (obj) มีการเชื่อมโยงอย่างแน่นแฟ้นกว่า obj.Save () ได้อย่างไร?" นี่เป็นตัวอย่างที่ผิด ตัวอย่างที่ถูกต้องจะเทียบกับAgent.Save(obj) agentInstance.Save(obj)ด้วยหลังคุณมีความเป็นไปได้ที่จะฉีด agentInstanceเข้าไปในรหัสโดยใช้ ผลที่ตามมาคุณสามารถฉีดระดับเด็ก ๆของAgentเกินไปซึ่งจะช่วยให้การใช้ซ้ำและใช้รหัสที่แตกต่างกันกับ "ประเภท" ของAgentโดยไม่ต้อง recompiling นี่คือการมีเพศสัมพันธ์ต่ำ
Timothy Truckle

ฉันคิดว่ามันเป็นสองสิ่ง จำเป็นต้องมีความยืดหยุ่นหรือไม่และจำเป็นต้องมีสถานะ global / instance หรือไม่ ขึ้นอยู่กับแต่ละ dev / สถาปนิกที่จะตัดสินใจ ฉันต้องการโค้ดเบสที่ง่ายกว่าการเพิ่มความซับซ้อนสำหรับสถานการณ์ที่ทำให้ทุกอย่างยากขึ้นที่จะเข้าใจโดยรวม สิ่งหนึ่งที่ฉันชอบเกี่ยวกับ node / js คือฉันสามารถเขียนโค้ดแบบง่าย ๆ / ทำความสะอาดและยังคงทำการทดสอบได้โดยไม่ต้องเขียนโค้ดลงใน DI / IoC
Tracker1

2

โดยส่วนตัวฉันคิดว่าส่วนสำคัญเพียงอย่างเดียวเกี่ยวกับชั้นเรียนผู้ช่วยดังกล่าวคือพวกเขาเป็นคนส่วนตัว นอกจากนั้น - พวกเขาเป็นความคิดที่ดีอย่างเคร่งครัด

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

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


1
คลาสยูทิลิตี้สาธารณะอาจยังคงมีประโยชน์ ตัวอย่างที่สำคัญ: java.lang.Math.
amon

1

ความชุกของstaticชั้นเรียนผู้ช่วยตามความเข้าใจผิด เพียงเพราะเราเรียกคลาสที่มีstaticเมธอดเท่านั้น"คลาสยูทิลิตี้" ไม่ได้หมายความว่ามันไม่ได้รับอนุญาตให้เขียนพฤติกรรมทั่วไปใน POJO

static คลาสตัวช่วยเป็นรูปแบบการต่อต้านด้วยเหตุผลสามประการ:

  1. การเข้าถึงคงผู้ช่วยนี้วิธีการซ่อนอ้างอิง ถ้า "ยูทิลิตี้คลาส" เหล่านี้เป็น POJO คุณสามารถแทรก int ไปยังคลาสที่ต้องพึ่งพาเป็นพารามิเตอร์ตัวสร้างซึ่งจะทำให้การอ้างอิงที่ชัดเจนสำหรับผู้ใช้ใด ๆ ของคลาสที่ขึ้นต่อกัน

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

  3. โดยเฉพาะอย่างยิ่งถ้าพวกเขารักษารัฐเหล่านี้เป็นเพียงตัวแปรทั่วโลก และหวังว่าจะไม่มีใครโต้แย้งว่าตัวแปรทั่วโลกนั้นดี ...

คลาสตัวช่วยคงที่เป็นส่วนหนึ่งของรูปแบบการต่อต้านรหัส STUPID


สถานะโกลบอลไม่เกี่ยวข้องกับคำถาม - max630

OP เขียนว่า:

แต่ส่วนใหญ่มันแน่นอนขึ้นอยู่กับบริบทและรัฐเต็ม

โครงสร้าง statefull คงเป็นรัฐทั่วโลก

รหัสใด ๆ สามารถใช้งานได้ - สูงสุด 630

ใช่สาเหตุ และเกือบทุกการใช้งานต้องชนิดของรัฐทั่วโลก

แต่ รัฐทั่วโลก ! = ตัวแปรทั่วโลก

คุณสามารถสร้าง สถานะโกลบอลด้วยเทคนิค OO ผ่านการฉีดพึ่งพาแต่คุณไม่สามารถหลีกเลี่ยงสถานะโกลบอลด้วยโครงสร้างสแตติกแบบ statefull ซึ่งเป็นตัวแปรโกลบอลที่ด้านล่าง


2
สถานะโกลบอลไม่เกี่ยวข้องกับคำถามรหัสชนิดใดก็ได้ที่สามารถใช้ได้
max630

@ max630 โปรดดูการอัปเดตของฉัน
Timothy Truckle

1
คุณสามารถใช้ฟังก์ชั่นฟรีคงที่โดยไม่ต้องเชื่อมต่อ คุณผ่านFunc<Result, Args>วัตถุที่มีการยกตัวอย่างในที่อื่น
Caleth

1
1) โดยทั่วไปฉันคิดว่าการซ่อนการใช้งานเป็นสิ่งที่ดีที่เหมาะสม 2) การมีทุกอย่างเป็นอาร์กิวเมนต์ / การพึ่งพาการฉีดยังสร้างการมีเพศสัมพันธ์ในเวลาออกแบบคุณสามารถรู้สึกได้เมื่อคุณพบว่าตัวเองต้องใช้เวลามากในการเปลี่ยนลายเซ็นในเครือพึ่งพาที่ยาวนาน และเช่นเดียวกับการมีทุกฟังก์ชั่นที่ต้องการ Logger ของคุณหรือข้อกังวลอื่น ๆ ตัดกันเป็นข้อถกเถียง ... (แต่ใช่มันสามารถทำการทดสอบในระดับต่ำได้ยากขึ้น) 3) แน่นอนว่าฟังก์ชั่นคงที่ควรเป็นแบบไร้สัญชาติ
อเล็กซ์

1
@ Alex จากนั้นให้ฉันบอกว่ามันวิธีอื่น ๆ : เป็นหน่วยเป็นพวงของรหัสใด ๆ (รวมทั้งแบบคงที่อ้างถึงวิธีการ "ยูทิลิตี้") ที่มีเหตุผลเดียวกันกับการเปลี่ยนแปลง สิ่งใดที่อยู่ภายในหน่วยนี้เป็นรายละเอียดการดำเนินงาน สิ่งอื่นใดคือการพึ่งพาและหน่วยไม่ควรมีการเข้าถึงแบบสแตติก
Timothy Truckle
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.