หลีกเลี่ยงกฎในพ่อมดและนักรบ


9

ในบทความบล็อกชุดนี้ Eric Lippert อธิบายถึงปัญหาในการออกแบบเชิงวัตถุโดยใช้พ่อมดและนักรบเป็นตัวอย่างโดยที่:

abstract class Weapon { }
sealed class Staff : Weapon { }
sealed class Sword : Weapon { }

abstract class Player 
{ 
  public Weapon Weapon { get; set; }
}
sealed class Wizard : Player { }
sealed class Warrior : Player { }

แล้วเพิ่มกฎสองสามข้อ:

  • นักรบสามารถใช้ดาบได้เท่านั้น
  • ตัวช่วยสร้างสามารถใช้พนักงานได้เท่านั้น

จากนั้นเขาก็จะแสดงให้เห็นถึงปัญหาที่คุณพบหากคุณพยายามบังคับใช้กฎเหล่านี้โดยใช้ระบบประเภท C # (เช่นทำให้Wizardชั้นเรียนมีความรับผิดชอบในการทำให้แน่ใจว่าตัวช่วยสร้างสามารถใช้พนักงานได้เท่านั้น) คุณละเมิดหลักการทดแทน Liskov, ความเสี่ยงข้อยกเว้นรันไทม์หรือจบลงด้วยรหัสที่ยากต่อการขยาย

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

player.Weapon = new Sword();

สถานะถูกแก้ไขโดยCommands และตามRules:

... เราทำให้Commandวัตถุที่เรียกWieldว่าใช้เวลาสองวัตถุเกมรัฐเป็นและPlayer Weaponเมื่อผู้ใช้ออกคำสั่งไปยังระบบ“ ตัวช่วยสร้างนี้ควรควงดาบนั้น” จากนั้นคำสั่งนั้นจะถูกประเมินในบริบทของชุดของRules ซึ่งสร้างลำดับของEffects เรามีสิ่งหนึ่งRuleที่บอกว่าเมื่อผู้เล่นพยายามควงอาวุธผลที่ได้คืออาวุธที่มีอยู่หากมีหนึ่งถูกทิ้งและอาวุธใหม่กลายเป็นอาวุธของผู้เล่น เรามีกฎอีกข้อหนึ่งที่เสริมความแข็งแกร่งให้กับกฎข้อแรกซึ่งระบุว่าเอฟเฟกต์ของกฎข้อแรกจะไม่นำมาใช้เมื่อวิซาร์ดพยายามใช้ดาบ

ฉันชอบแนวคิดนี้ในหลักการ แต่มีข้อกังวลเกี่ยวกับวิธีการใช้ในทางปฏิบัติ

ไม่มีอะไรน่าจะป้องกันไม่ให้นักพัฒนาจากหลีกเลี่ยงCommandsและRules โดยเพียงแค่การตั้งค่าบนWeapon คุณสมบัติความต้องการที่จะเข้าถึงได้โดยคำสั่งดังนั้นจึงไม่สามารถที่จะทำPlayerWeaponWieldprivate set

ดังนั้นสิ่งที่ทำให้นักพัฒนาไม่สามารถทำสิ่งนี้ได้? พวกเขาแค่จำไม่ได้ใช่ไหม


2
ฉันไม่คิดว่าคำถามนี้เป็นภาษาเฉพาะ (C #) เนื่องจากเป็นคำถามเกี่ยวกับการออกแบบ OOP โปรดพิจารณาลบแท็ก C #
อาจจะ_Factor

1
@maybe_factor c # แท็กใช้ได้เพราะรหัสที่โพสต์คือ c #
เข้ารหัสโยชิ

ทำไมคุณไม่ถาม @EricLippert โดยตรง ดูเหมือนว่าเขาจะปรากฏที่นี่ในเว็บไซต์นี้เป็นครั้งคราว
Doc Brown

@Maybe_Factor - ฉันข้ามไปแท็ก C # แต่ตัดสินใจเก็บไว้ในกรณีที่มีวิธีแก้ปัญหาเฉพาะภาษา
เบ็น L

1
@DocBrown - ฉันโพสต์คำถามนี้ในบล็อกของเขา (เพียงไม่กี่วันที่ผ่านมาเป็นที่ยอมรับ; ฉันไม่ได้รอนานที่จะตอบสนอง) มีวิธีที่จะนำคำถามของฉันมาที่นี่เพื่อความสนใจของเขา?
เบ็น L

คำตอบ:


9

อาร์กิวเมนต์ทั้งหมดที่ชุดบทความบล็อกนำไปสู่อยู่ในส่วนที่ห้า :

เราไม่มีเหตุผลที่จะเชื่อว่าระบบประเภท C # ได้รับการออกแบบมาให้มีความเพียงพอในการเข้ารหัสกฎของ Dungeons & Dragons ดังนั้นทำไมเราถึงต้องลอง

เราได้แก้ไขปัญหาของ“ รหัสไปที่แสดงกฎของระบบที่ไหน?” มันไปในวัตถุที่แสดงถึงกฎของระบบไม่ใช่ในวัตถุที่แสดงถึงสถานะของเกม ความกังวลของวัตถุของรัฐคือการรักษาสถานะของพวกเขาสอดคล้องกันไม่ได้อยู่ในการประเมินกฎของเกม

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

หากนักพัฒนาต้องการสร้างระบบกฎข้อที่สองซึ่งทำสิ่งต่าง ๆ ด้วยตัวละครและอาวุธที่ระบบกฎข้อแรกไม่อนุญาตพวกเขาสามารถทำเช่นนั้นได้เพราะใน C # คุณไม่สามารถ (ไม่มีแฮ็กการสะท้อนกลับที่น่ารังเกียจ) หาวิธีโทรมา จาก.

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


4

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

ฉันจะเริ่มต้นด้วยการพยายามที่จะได้รับข้อกำหนดการทำงานจริง ตัวอย่างเช่น: "ผู้เล่นใด ๆ สามารถโจมตีผู้เล่นอื่น ... " ที่นี่:

interface Player {
    void Attack(Player enemy);
}

"ผู้เล่นสามารถควงอาวุธที่ใช้ในการโจมตีพ่อมดสามารถควงไม้เท้านักรบนักรบ":

public class Wizard: Player {
    ...
    public void Wield(Staff weapon) { ... }
    ...
}
public class Warrior: Player {
    ...
    public void Wield(Sword sword) { ... }
    ...
}

"อาวุธแต่ละชิ้นสร้างความเสียหายแก่ศัตรูที่ถูกโจมตี" ตกลงตอนนี้เราต้องมีอินเตอร์เฟสทั่วไปสำหรับ Weapon:

interface Weapon {
    void dealDamageTo(Player enemy);
}

และอื่น ๆ ... ทำไมไม่มีWield()ในPlayer? เพราะไม่มีข้อกำหนดที่ผู้เล่นสามารถใช้อาวุธใด ๆ ได้

ฉันสามารถอิมเมจว่าจะมีข้อกำหนดที่ระบุว่า: "ใด ๆPlayerอาจพยายามควง ๆWeapon" อย่างไรก็ตามนี่จะเป็นสิ่งที่แตกต่างอย่างสิ้นเชิง ฉันจะแบบมันบางทีด้วยวิธีนี้:

interface Player {
    void Attack(Player enemy);
    void TryWielding(Weapon weapon); // Throws UnwieldableException
}

สรุป: วางโมเดลข้อกำหนดและข้อกำหนดเท่านั้น อย่าสร้างแบบจำลองข้อมูลที่ไม่ใช่แบบจำลอง oo


1
คุณอ่านซีรี่ส์หรือไม่ บางทีคุณอาจต้องการบอกผู้แต่งชุดข้อมูลว่าไม่ใช่แบบจำลองข้อมูล แต่ต้องการ คำถามที่คุณมีในคำตอบของคุณคือข้อกำหนดในการแต่งหน้าไม่ใช่ข้อกำหนดที่ผู้เขียนมีเมื่อสร้างคอมไพเลอร์ C #
CodingYoshi

2
Eric Lippert อธิบายรายละเอียดของปัญหาทางเทคนิคในซีรี่ส์นั้น คำถามนี้เกี่ยวกับปัญหาจริง แต่ไม่ใช่คุณสมบัติ C # จุดของฉันคือในโครงการที่จริงเราควรที่จะทำตามความต้องการของธุรกิจ (ซึ่งผมให้ตัวอย่างที่ทำขึ้นใช่) ไม่ถือว่าความสัมพันธ์และคุณสมบัติ นั่นคือวิธีที่คุณจะได้รูปแบบที่เหมาะกับคุณ ซึ่งเป็นคำถาม
Robert Bräutigam

นั่นเป็นสิ่งแรกที่ฉันคิดว่าเมื่ออ่านซีรี่ส์ ผู้เขียนเพิ่งสร้าง abstractions ขึ้นมาโดยไม่เคยประเมินพวกเขาต่อไปเพียงแค่ติดกับพวกเขา พยายามที่จะแก้ปัญหาโดยอัตโนมัติครั้งแล้วครั้งเล่า แทนที่จะคิดเกี่ยวกับโดเมนและ abstractions ที่มีประโยชน์ที่ควรจะไปก่อน upvote ของฉัน
Vadim Samokhin

นี่คือคำตอบที่ถูกต้อง บทความแสดงข้อกำหนดที่ขัดแย้งกัน (ข้อกำหนดหนึ่งกล่าวว่าผู้เล่นสามารถใช้อาวุธ [ใด ๆ ] ในขณะที่ข้อกำหนดอื่นบอกว่านี่ไม่ใช่กรณี) แล้วรายละเอียดว่าระบบยากที่จะแสดงความขัดแย้งอย่างถูกต้อง คำตอบเดียวที่ถูกต้องคือการลบข้อขัดแย้ง ในกรณีนี้หมายถึงลบข้อกำหนดที่ผู้เล่นสามารถใช้อาวุธใด ๆ
Daniel T.

2

วิธีการหนึ่งที่จะส่งคำสั่งไปยังWield Playerจากนั้นผู้เล่นจะดำเนินการWieldคำสั่งซึ่งตรวจสอบกฎที่เหมาะสมและส่งคืนค่าWeaponซึ่งPlayerจากนั้นตั้งค่าฟิลด์อาวุธของตนเองด้วย ด้วยวิธีนี้ฟิลด์อาวุธสามารถมีตัวตั้งค่าส่วนตัวและสามารถตั้งค่าได้ผ่านการส่งWieldคำสั่งไปยังผู้เล่นเท่านั้น


จริงๆแล้วสิ่งนี้ไม่ได้แก้ปัญหา นักพัฒนาที่สร้างวัตถุคำสั่งอาจผ่านอาวุธใด ๆ และผู้เล่นจะตั้งค่า ไปอ่านซีรี่ส์เพราะปัญหายากกว่าที่คุณคิด ที่จริงแล้วเขาทำซีรีส์นั้นเพราะเขาเจอปัญหาการออกแบบนี้ในขณะที่พัฒนาคอมไพเลอร์ Roslyn C #
CodingYoshi

2

ไม่มีสิ่งใดป้องกันไม่ให้ผู้พัฒนาทำเช่นนั้น อันที่จริง Eric Lippert ลองใช้เทคนิคต่าง ๆ มากมาย แต่พวกเขาทั้งหมดมีจุดอ่อน นั่นคือประเด็นทั้งหมดของซีรีส์ที่หยุดไม่ให้ผู้พัฒนาทำเช่นนั้นไม่ใช่เรื่องง่ายและทุกสิ่งที่เขาพยายามมีข้อเสีย ในที่สุดเขาก็ตัดสินใจว่าการใช้Commandวัตถุที่มีกฎเป็นวิธีที่จะไป

ด้วยกฎคุณสามารถตั้งค่าWeaponคุณสมบัติของ a Wizardให้เป็นSwordแต่เมื่อคุณขอWizardให้ใช้อาวุธ (ดาบ) และการโจมตีมันจะไม่มีผลใด ๆ ดังนั้นจึงจะไม่เปลี่ยนสถานะใด ๆ ตามที่เขาพูดด้านล่าง:

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

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

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

ฉันคิดว่ามันเป็นทางออกที่ดี แม้ว่าในบางกรณีฉันจะไปกับรูปแบบลองตั้งเกินไป


This solution basically says you can set any weapon but when you yield it, if not the right weapon, it would be essentially useless.ฉันไม่สามารถหามันได้ในซีรีส์นั้นคุณช่วยชี้ให้ฉันดูว่าโซลูชันนี้เสนอให้ที่ไหน?
Vadim Samokhin

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

อืมฉันคิดว่าการถือดาบโดยทั่วไปหมายความว่าควรจะตั้งใช่ไหม? that the existing weapon, if there is one, is dropped and the new weapon becomes the player’s weaponเมื่อผมอ่านวรรคนั้นผมตีความว่าผลที่กฎข้อแรกคือ ในขณะที่กฎข้อที่สองซึ่งthat strengthens the first rule, that says that the first rule’s effects do not apply when a wizard tries to wield a sword.ฉันคิดว่ามีการตรวจสอบกฎว่าอาวุธเป็นดาบหรือไม่ดังนั้นมันจึงไม่สามารถถูกใช้โดยพ่อมดได้ดังนั้นจึงไม่ได้ตั้งค่า แทนที่จะเป็นเสียงทรอมโบนที่น่าเศร้า
Vadim Samokhin

สำหรับความคิดของฉันมันจะแปลกที่กฎคำสั่งบางอย่างถูกละเมิด มันเหมือนการเบลอของปัญหา ทำไมการจัดการปัญหานี้หลังจากกฎถูกละเมิดอยู่แล้วและการตั้งค่าตัวช่วยสร้างให้อยู่ในสถานะที่ไม่ถูกต้อง ตัวช่วยสร้างไม่สามารถมีดาบได้ แต่ทำเช่นนั้น! ทำไมไม่ปล่อยให้มันเกิดขึ้น?
Vadim Samokhin

ฉันเห็นด้วยกับ @Zapadlo เกี่ยวกับวิธีตีความWieldที่นี่ ฉันคิดว่ามันเป็นชื่อที่ทำให้เข้าใจผิดเล็กน้อยสำหรับคำสั่ง สิ่งที่ต้องการChangeWeaponจะแม่นยำมากขึ้น ผมคิดว่าคุณอาจมีรูปแบบที่แตกต่างกันที่คุณสามารถตั้งค่าอาวุธใด ๆ แต่เมื่อคุณผลผลิตมันถ้าไม่ได้เป็นอาวุธที่เหมาะสมก็จะไร้ประโยชน์เป็นหลัก ฟังดูน่าสนใจ แต่ฉันไม่คิดว่ามันคือสิ่งที่ Eric Lippert อธิบาย
เบ็น L

2

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

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

โดยสรุปสิ่งเดียวที่สามารถป้องกันนักพัฒนาจากการทำผิดพลาดคือการมีชุดทดสอบ (หน่วย) ที่ตรวจสอบว่ากฎทั้งหมดได้รับการปฏิบัติตาม


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

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

1

ฉันอาจพลาดความละเอียดอ่อนที่นี่ แต่ฉันไม่แน่ใจว่าปัญหาเกิดขึ้นกับระบบพิมพ์ อาจจะมีการประชุมใน C #

ตัวอย่างเช่นคุณสามารถทำให้ประเภทนี้ปลอดภัยโดยการWeaponตั้งค่าตัวป้องกันPlayerไว้ จากนั้นเพิ่มsetSword(Sword)และsetStaff(Staff)ไปยังWarriorและWizardตามลำดับที่เรียกตัวตั้งค่าที่มีการป้องกัน

วิธีการที่การPlayer/ Weaponความสัมพันธ์แบบคงที่มีการตรวจสอบและรหัสที่ไม่สนใจก็สามารถใช้ที่จะได้รับPlayerWeapon


Eric Lippert ไม่ต้องการโยนข้อยกเว้น คุณอ่านซีรี่ส์หรือไม่ การแก้ปัญหาต้องเป็นไปตามข้อกำหนดและข้อกำหนดนี้มีการระบุไว้อย่างชัดเจนในชุด
CodingYoshi

@ การเข้ารหัสโยชิทำไมนี่จะโยนข้อยกเว้น? มันปลอดภัยประเภทเช่นตรวจสอบได้ในเวลารวบรวม
อเล็กซ์

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

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

@CodingYoshi ตอนนี้ไม่ได้หมายความว่าคุณสามารถรหัสไม่ได้เขียนว่าจะต้องมีการตรวจสอบเช่นรันไทม์ถ้าคุณพยายามที่จะเพิ่มไปยังWeapon Playerแต่ไม่มีระบบพิมพ์ที่คุณไม่ทราบประเภทคอนกรีตในเวลารวบรวมที่สามารถกระทำกับคอนกรีตเหล่านั้นในเวลารวบรวม ตามคำจำกัดความ รูปแบบนี้หมายถึงว่าเป็นกรณีที่จำเป็นต้องได้รับการจัดการที่รันไทม์เท่านั้นดังนั้นจึงดีกว่ารูปแบบของ Eric
อเล็กซ์

0

ดังนั้นสิ่งที่ทำให้นักพัฒนาไม่สามารถทำสิ่งนี้ได้? พวกเขาแค่จำไม่ได้ใช่ไหม

คำถามนี้มีประสิทธิภาพเช่นเดียวกันกับหัวข้อ Holy-war-ish ที่เรียกว่า " ตำแหน่งที่จะทำการตรวจสอบ " (ส่วนใหญ่อาจสังเกตววววววววว)

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

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

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