ประโยชน์ที่ได้รับจากแบบจำลอง POCO ล้วนคืออะไร


16

ประโยชน์หลักของการมีโมเดล POCO บริสุทธิ์คืออะไร ฉันได้รับแบบจำลองที่ควรจะสะอาดและเรียบง่าย แต่ฉันมักจะชอบที่จะให้การดูแลรักษาวัตถุเด็กในชั้นเรียนรูปแบบ ตัวอย่างเช่นถ้าฉันมีClassAและClassBกำหนดดังนี้

public class ClassA
{
    public string MyProp { get; set; }
    public IEnumerable<ClassB> Children { get; }

    public void AddChild(ClassB newChild) { /*... */ }
    public void RemoveChild(ClassB child) { /* ... */ }
}

public class ClassB
{
    public string SomeProp { get; set; }
} 

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

ความช่วยเหลือใด ๆ ที่มีความนิยมขอบคุณ


ฉันจะลบวิธีการเพิ่ม / ลบเว้นแต่ว่าพวกเขาจะเพิ่มค่าบางอย่างเช่นการแปลอาร์กิวเมนต์ ClassB เป็นโมฆะเป็นวัตถุรูปแบบรุ่น NullObject:AddChild(ClassB newChild) => Children.Add(newChild ?? new NullClassB())
เกรแฮม

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

เหตุผลหลักในการหลีกเลี่ยงการออกแบบนี้เป็นเพราะมันขัดกับแนวทางการออกแบบ. net มันเป็นสิ่งที่ไม่มีข้อ จำกัด แต่ผู้คนคาดหวังว่าคอลเลกชันจะมีวิธีการกลายพันธุ์
Frank Hileman

@Casey ฉันไม่ได้ใช้รูปแบบ Active Record วิธีการเพิ่มจะทำการตรวจสอบความถูกต้องของข้อมูลเล็กน้อย มีวิธีการลบเนื่องจากไม่มีการรวบรวมพวกเขาเพียงแค่เพิ่มและลบออกจากรายการภายใน ฉันได้เปลี่ยนมันไปแล้วแม้ว่าจะใช้ประเภทคอลเลกชันที่แตกต่างกันซึ่งทำให้ฉันสามารถตรวจสอบความถูกต้องได้ในขณะที่ยังคงใช้เมธอด Add / Remove ในตัว
Jesse

คำตอบ:


43

คำถามสองข้อของคุณไม่เกี่ยวข้อง

ประโยชน์ที่ได้รับจากแบบจำลอง POCO ล้วนคืออะไร

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

POCO ไม่มีอะไรมากไปกว่าแนวคิดของ POJO J เปลี่ยนเป็น C เพราะคนดูตลกเมื่อคุณอธิบายแนวคิดที่มี Java ในชื่อถ้าคนเหล่านั้นใช้ C # ความคิดไม่ได้ขึ้นอยู่กับภาษา พวกเขาอาจเรียกมันว่า Plain Old Objects แต่ใครอยากคุยโม้เกี่ยวกับการใช้ POO

ฉันจะให้ Fowler อธิบายถึงที่มา:

คำประกาศเกียรติคุณในขณะที่ Rebecca Parsons, Josh MacKenzie และฉันกำลังเตรียมตัวสำหรับการพูดคุยในการประชุมในเดือนกันยายน 2000 ในการพูดคุยเราได้ชี้ให้เห็นถึงประโยชน์มากมายของการเข้ารหัสตรรกะทางธุรกิจลงในวัตถุจาวาปกติแทนที่จะใช้ Entity Beans เราสงสัยว่าทำไมผู้คนถึงต่อต้านการใช้วัตถุปกติในระบบของพวกเขาและสรุปว่าเป็นเพราะวัตถุธรรมดา ๆ ไม่มีชื่อแฟนซี ดังนั้นเราจึงให้พวกเขาหนึ่งอันและมันก็ติดแน่นมาก

martinfowler.com: POJO

สำหรับคำถามอื่น ๆ ของคุณ:

มีบางอย่างผิดปกติในการเพิ่มและลบวิธีการหรือไม่

ฉันไม่ชอบโดยตรงรู้เกี่ยวกับA Bแต่นั่นเป็นสิ่งที่กรมทรัพย์สินทางปัญญาไม่ใช่สิ่งPOJO


ฉันมีการพึ่งพาโดยตรงเพื่อBประโยชน์ของความเรียบง่ายโดยหลักการแล้วสิ่งเหล่านี้จะใช้อินเทอร์เฟซ แต่ยังคงมีรายชื่อของA IInterfaceBมีบางอย่างผิดปกติกับAddChildวิธีการหรือไม่หากเด็ก ๆ เชื่อมโยงอย่างหลวม ๆ ผ่านการอ้างอิงส่วนต่อประสาน?
Jesse

6
ฉันสามารถทำสิ่งโง่ ๆ มากมายเพื่อเห็นแก่ความเรียบง่าย สิ่งที่ฉันไม่ชอบคือ A รู้เกี่ยวกับ B. A ไม่ได้ใช้ B ดังนั้นไม่จำเป็นต้องกำหนดอินเทอร์เฟซที่เป็นเจ้าของ A ที่เหมาะสมเพื่อพูดคุยกับ B ถึง เท่าที่ฉันบอกได้ก็คือชุดสะสม ดังนั้น A ควรจัดการกับ B ผ่าน<T>ดังนั้นจึงไม่จำเป็นต้องรู้อะไรเกี่ยวกับมัน
candied_orange

2
ฉันได้เห็น "PODO" สำหรับ "วัตถุข้อมูลเก่าธรรมดา" เพื่อหลีกเลี่ยงตัวระบุภาษาใด ๆ ในคำย่อ PODO ฟังดูงี่เง่านิดหน่อย (ค่อนข้างฟังดูเหมือนคำที่คุณได้ยินบน Tatooine ถึงฉัน) มากกว่า POJO หรือ POCO ฉันคิดว่า แต่โง่น้อยกว่า POO อย่างมาก
KRyan

2
ฉันสงสัยว่าการนำเสนอของ Fowler จะหายไปได้อย่างไรถ้าเขาเรียกพวกเขาว่า POO
โอลิเวอร์

3

ด้วย Add and Remove คุณกำลังใช้งานCollection<T>คุณสมบัติต่างๆ ถามตัวคุณเองว่าทำไมคุณถึงใช้IEnumerable<T>แทนList<T>หรือบางคลาสที่เปลี่ยนแปลงไม่ได้? เห็นได้ชัดว่าไม่ใช่เพราะคอลเลกชันของคุณควรเป็นแบบอ่านอย่างเดียว

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

แต่ดูเหมือนว่าสำหรับฉันฉันList<ClassB>อาจจะให้บริการคุณได้ดี


0

สิ่งที่AddChildเพิ่มไปและRemoveChildลบออกจาก? หากมาจากฐานข้อมูล (หรือที่เก็บข้อมูลประเภทใดก็ตาม) แสดงว่าคุณมี Active Record อยู่ ไม่จำเป็นว่าจะเป็นเรื่องเลวร้ายเสมอไป แต่มันทำให้คุณใกล้ชิดกับการต้องกังวลเกี่ยวกับกรอบการประชุมการพึ่งพา ฯลฯ ตามที่ @CandiedOrange กล่าวถึง

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

เหตุผลเดียวที่ทำให้มันซับซ้อนเล็กน้อยก็คือดูเหมือนว่าคุณมีความต้องการที่จะจัดการอย่างชัดเจนว่า ClassB จะเชื่อมโยงและแยกออกจาก ClassA อย่างไร ดังนั้นคุณมีพฤติกรรมเล็กน้อยที่จะใช้ คุณสามารถนำไปใช้ภายในคลาสได้ (ซึ่ง "ถูกกฎหมาย" ทั้งหมดดู/programming//a/725365/44586 ) หรือคุณสามารถมีคลาสแยกต่างหากที่มีพฤติกรรมดังกล่าว ทำสิ่งที่เหมาะสมที่สุดสำหรับสถานการณ์ส่วนบุคคลของคุณ

ไม่ว่าในกรณีใดก็ตาม POJO / POCO เป็นเพียง OOP จริง ๆ เพราะมันหมายถึงการไม่ได้ตกแต่งและไม่มีภาระผูกพัน ปฏิบัติตามหลักการของ OOP และคุณจะปลอดภัย


จริงๆแล้ว AddChild กำลังตรวจสอบความซ้ำซ้อนและเป็นโมฆะและไม่อนุญาต RemoveChild อยู่ที่นั่นเพราะเพื่อป้องกันไม่ให้แบ็คดอร์เพิ่มคอลเลคชั่นถูกเปิดเผยเป็น IEnumerable มันจะทำการลบมาตรฐานออกจากคอลเลกชันเท่านั้น
Jesse

1
ขอบคุณที่อธิบาย ใช่ฟังดูเหมือนว่าเป็นประเภทของพฤติกรรมที่ควรจะเป็นใน POCO และดีกว่าการเปิดเผย IEn ของคุณพื้นฐานสำหรับผู้โทรเพื่อปรับเปลี่ยนหรือแทนที่ตามความประสงค์
John M Gant

ฉันคิดว่า Active Record เป็นเพียงรูปแบบที่ไม่ดี
Casey

1
@Casey คุณจะไม่ได้รับข้อโต้แย้งใด ๆ จากฉันเกี่ยวกับเรื่องนี้ แต่ฉันจะไม่เถียงว่าใครบางคนต้องการที่จะใช้มันอย่างใดอย่างหนึ่ง ประเด็นหลักคือถ้า Jesse ตั้งใจจะใช้รูปแบบเช่น Active Record ที่รวมการคงอยู่กับคำจำกัดความของแบบจำลองเขาจะมีปัญหาทั้งหมดที่ไฮไลท์ของ CandiedOrange และจะไม่ถือว่าเป็น POCO อย่างแท้จริงสำหรับสิ่งที่คุ้มค่า แต่นั่นไม่ใช่สิ่งที่เขาทำอยู่แล้ว
John M Gant
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.