'กฎของ Demeter' ใช้กับลายเซ็นวิธีสาธารณะ / API หรือไม่


10

เนื่องจากการเปลี่ยนแปลงของ API / วิธีการลงนามสาธารณะควรมีเพียงเล็กน้อยเพื่อป้องกันการแตกรหัสลูกค้าที่ใช้วิธีการเหล่านี้ฉันสงสัยว่ากฎหมายของ Demeterนั้นมีผลบังคับใช้น้อยกว่านี้หรือไม่

ตัวอย่างง่ายๆ:

class Account() {
   double balance;
   public void debit(Transaction t) {
      balance -= t.getAmount();
   }
}

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

สิ่งนี้ทำให้เป็นตัวเลือกที่สมเหตุสมผลหรือไม่? หรือฉันกำลังพลาดอะไรอยู่?

คำตอบ:


3

แต่นี่ไม่ได้ละเมิดกฎหมายของ Demeter

ยิ่งกว่านั้นอย่างเป็นทางการแล้วกฎหมายของ Demeter สำหรับฟังก์ชั่นกำหนดให้วิธีการ M ของวัตถุ O อาจเรียกใช้วิธีการของวัตถุประเภทต่อไปนี้เท่านั้น:

  • โอตัวเอง
  • พารามิเตอร์ของ M
  • วัตถุใด ๆ ที่สร้าง / สร้างอินสแตนซ์ภายใน M
  • วัตถุองค์ประกอบโดยตรงของ O
  • ตัวแปรโกลบอลซึ่งสามารถเข้าถึงได้โดย O ในขอบเขตของ M

Wikipedia: กฎหมายของ Demeter

ทรานแซกชันเป็นอาร์กิวเมนต์ของวิธีการเดบิตดังนั้นการเรียก t.getAmount () เป็นเรื่องปกติ

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

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


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

แก้ไข 2 เป็นเรื่องส่วนตัวฉันเห็นด้วย
Sean

0

หากคุณวางแผนที่จะขยายAccountชั้นเรียนในอนาคตฉันจะบอกว่านี่เป็นสถานการณ์ที่ทำให้Transactionวัตถุมีวัตถุประสงค์ทั่วไปมากขึ้นจะเป็นการดีในการดัดกฎของกฎหมาย

ตัวอย่างเช่น:

public class Amount {

    public void process( Transaction t ) {
        ....
    }
}

public abstract class Transaction {

    public String getType();

}

ฉันคิดว่าฉันหลงทางจากคำถามดั้งเดิม แต่ประเด็นของฉันคือในขณะที่คุณอาจกังวลว่าคุณกำลังพลัดหลงจากกฎแห่ง Demeter ข้อดีของการทำเช่นนั้นมีมากกว่าเชิงลบ

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