ฉันกำลังติดตามคำถามนี้แต่ฉันเปลี่ยนโฟกัสจากโค้ดเป็นหลักการ
จากความเข้าใจของฉันเกี่ยวกับหลักการทดแทน Liskov (LSP) ไม่ว่าวิธีการใดที่อยู่ในคลาสพื้นฐานของฉันพวกเขาจะต้องดำเนินการในคลาสย่อยของฉันและตามหน้านี้หากคุณแทนที่วิธีในคลาสพื้นฐานและไม่ทำอะไรเลย คุณกำลังละเมิดหลักการ
ตอนนี้ปัญหาของฉันสามารถสรุปได้เช่นนี้ฉันมีนามธรรมWeapon
class
และสองชั้นและSword
Reloadable
หากReloadable
มีข้อมูลเฉพาะที่method
เรียกว่าReload()
ฉันจะต้องลดความเร็วเพื่อเข้าถึงmethod
และถ้าคุณต้องการหลีกเลี่ยงปัญหานั้น
Strategy Pattern
จากนั้นผมก็คิดของการใช้ วิธีนี้แต่ละอาวุธเป็นเพียงตระหนักถึงการกระทำที่มีความสามารถในการดำเนินการดังนั้นสำหรับตัวอย่างเช่นReloadable
อาวุธอย่างเห็นได้ชัดสามารถโหลด แต่ไม่สามารถและไม่ได้ตระหนักถึงSword
Reload class/method
ตามที่ระบุไว้ในโพสต์ Stack Overflow ของฉันฉันไม่จำเป็นต้องลดความเร็วและฉันสามารถเก็บList<Weapon>
สะสม
ในฟอรัมอื่นคำตอบแรกที่แนะนำเพื่อให้Sword
ระวังReload
เพียงไม่ทำอะไรเลย ได้รับคำตอบเดียวกันนี้ในหน้า Stack Overflow ที่ฉันลิงค์ไปด้านบน
ฉันไม่เข้าใจว่าทำไม ทำไมการละเมิดหลักการและอนุญาตให้ Sword ต้องระวังReload
และปล่อยให้มันว่างเปล่า อย่างที่ฉันบอกไว้ในโพสต์ Stack Overflow SP จะแก้ปัญหาของฉันได้ค่อนข้างมาก
ทำไมมันไม่เป็นทางออกที่ทำงานได้?
public final Weapon{
private final String name;
private final int damage;
private final List<AttackStrategy> validactions;
private final List<Actions> standardActions;
private Weapon(String name, int damage, List<AttackStrategy> standardActions, List<Actions> attacks)
{
this.name = name;
this.damage = damage;
standardActions = new ArrayList<Actions>(standardActions);
validAttacks = new ArrayList<AttackStrategy>(validActions);
}
public void standardAction(String action){} // -- Can call reload or aim here.
public int attack(String action){} // - Call any actions that are attacks.
public static Weapon Sword(String name, damage, List<AttackStrategy> standardActions, List<Actions> attacks){
return new Weapon(name, damage,standardActions, attacks) ;
}
}
อินเตอร์เฟซการโจมตีและการใช้งาน:
public interface AttackStrategy{
void attack(Enemy enemy);
}
public class Shoot implements AttackStrategy {
public void attack(Enemy enemy){
//code to shoot
}
}
public class Strike implements AttackStrategy {
public void attack(Enemy enemy){
//code to strike
}
}
reload()
ว่างไว้หรือstandardActions
ไม่ประกอบด้วยการบรรจุซ้ำเป็นเพียงกลไกที่แตกต่างกัน ไม่มีความแตกต่างพื้นฐาน คุณสามารถทำได้ทั้งสองอย่าง => ทางออกของคุณเป็นไปได้ (ซึ่งเป็นคำถามของคุณ); Sword ไม่จำเป็นต้องรู้เรื่องการรีโหลดถ้า Weapon นั้นมีการใช้งานเป็นค่าว่างเปล่า
class Weapon { bool supportsReload(); void reload(); }
คุณสามารถทำได้ ลูกค้าจะทดสอบว่ารองรับก่อนโหลดซ้ำหรือไม่reload
จะถูกกำหนดตามสัญญาที่จะโยน!supportsReload()
IFF ที่เป็นไปตาม LSP iff ขับเคลื่อนคลาสที่เป็นไปตามโปรโตคอลที่ฉันเพิ่งอธิบาย