การออกแบบ OO ใดที่จะใช้ (มีรูปแบบการออกแบบ)


11

ฉันมีวัตถุสองชิ้นที่แสดงถึง 'บาร์ / คลับ' (สถานที่ที่คุณดื่ม / สังสรรค์)

ในสถานการณ์หนึ่งฉันต้องการชื่อบาร์ที่อยู่ระยะทางสโลแกน

ในสถานการณ์อื่นฉันต้องการชื่อบาร์, ที่อยู่, URL เว็บไซต์, โลโก้

ดังนั้นฉันจึงมีวัตถุสองชิ้นที่เป็นตัวแทนของสิ่งเดียวกัน แต่มีเขตข้อมูลที่แตกต่างกัน

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

ตัวเลือกหนึ่งคือการมีสองคอนสตรัคเตอร์และโมฆะสาขาอื่น ๆ เช่น:

class Bar {
     private final String name;
     private final Distance distance;
     private final Url url;

     public Bar(String name, Distance distance){
          this.name = name;
          this.distance = distance;
          this.url = null;
     }

     public Bar(String name, Url url){
          this.name = name;
          this.distance = null;
          this.url = url;
     }

     // getters
}

ฉันไม่ชอบสิ่งนี้เพราะคุณจะต้องตรวจสอบ null เมื่อคุณใช้ getters

ในตัวอย่างจริงของฉันสถานการณ์แรกมี 3 ฟิลด์และสถานการณ์ที่สองมีประมาณ 10 ดังนั้นมันจึงเป็นความเจ็บปวดที่แท้จริงที่มีสองคอนสตรัคเตอร์จำนวนฟิลด์ที่ฉันจะต้องประกาศว่างแล้วเมื่อวัตถุที่คุณใช้คุณจะไม่ ไม่ทราบว่าBarคุณกำลังใช้ที่ใดและฟิลด์ใดเป็นโมฆะและอะไรที่ไม่ได้

ฉันมีตัวเลือกอื่น ๆ อีกบ้าง?

สองคลาสเรียกว่าBarPreviewและBar?

การสืบทอด / อินเตอร์เฟสบางประเภท?

มีอะไรอีกบ้างที่ยอดเยี่ยม?


29
ว้าวคุณได้ใช้Barตัวระบุที่ถูกต้องตามกฎหมายแล้ว!
Mason Wheeler

1
หากคุณแบ่งปันคุณสมบัติบางอย่างหนึ่งตัวเลือกคือการใช้คลาสพื้นฐาน
Yusubov

1
ฉันไม่เคยคิดอย่างนั้น การเขียนรหัสใด ๆ สำหรับร้านขายสุนัขบาร์ / ฟูของฉันอาจทำให้สับสนได้
Erik Reppen


4
@gnat ผู้คนคาดเดาได้อย่างไร จากคำพูดลิงค์ของคุณ: You should only ask practical, answerable questions based on actual problems that you face.และนั่นคือสิ่งที่เกิดขึ้นที่นี่
Blundell

คำตอบ:


9

ความคิดของฉัน:

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

อย่างไรก็ตามคุณมีสองตำแหน่งที่ต้องการข้อมูลของวัตถุแถบนี้และทั้งสองต้องการเพียงส่วนย่อยเท่านั้น (และคุณไม่ต้องการให้มีการเปลี่ยนแปลงข้อมูล) คำตอบปกติคือ "วัตถุการถ่ายโอนข้อมูล" หรือ DTO; POJO (วัตถุ Java ol ธรรมดา ') ที่มีตัวรับคุณสมบัติที่ไม่เปลี่ยนรูป DTO เหล่านี้สามารถสร้างได้โดยการเรียกใช้เมธอดบนวัตถุโดเมนบาร์หลัก: "toScenario1DTO ()" และ "toScenario2DTO ()"; ผลลัพธ์ที่ได้คือ DTO ที่มีความชุ่มชื้น (หมายถึงคุณจะต้องใช้ Constructor ที่ยาวและซับซ้อนในที่เดียว)

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

แก้ไข:เพื่อให้ตัวอย่าง:

public class Bar {
     private String name;
     private Address address; 
     private Distance distance;
     private Url url;
     private Image logo;
     private string Slogan;

     public OnlineBarDto ToOnlineDto()
     {
         return new OnlineBarDto(name, address, url, logo);
     }

     public PhysicalBarDto ToPhysicalDto()
     {
         return new PhysicalBarDto(name, address, distance, slogan);
     }

     public void UpdateFromDto(PhysicalBarDto dto)
     {
         //validation logic here, or mixed into assignments

         name = dto.Name;
         address = dto.Address;
         distance = dto.Distance;
         slogan = dto.Slogan;
     }

     public void UpdateFromDto(OnlineBarDto dto)
     {
         //Validate DTO fields before performing assignments

         name = dto.Name;
         address = dto.Address;
         url= dto.Url;
         logo = dto.Logo;
     }

     // getters/setters - As necessary within the model and data access layers;
     // other classes can update the model using DTOs, forcing validation.
}

public class PhysicalBarDto
{
     public final String Name;
     public final Address Address;
     public final Distance Distance;
     public final String Slogan;

     public PhysicalBarDto(string Name, Address address, Distance distance, string slogan) 
     { //set instance fields using parameter fields; you know the drill }
}

public class OnlineBarDto
{
     public final String Name;
     public final Address Address;
     public final Image Logo;
     public final Url Url;

     public OnlineBarDto(string Name, Address address, Url url, Image logo) 
     { //ditto }
}

คลาส Address, Distance และ Url ควรจะไม่เปลี่ยนรูปแบบด้วยตนเองหรือเมื่อใช้ใน DTO พวกเขาควรถูกแทนที่ด้วย counterparts ที่ไม่เปลี่ยนรูป


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

1
DTO ย่อมาจาก "data transfer Object" และหมายถึงคลาสข้อมูลของโครงสร้างที่ง่ายมากที่ใช้ในการย้ายข้อมูลจากเลเยอร์โดเมน "รวย" ไปยังเลเยอร์ด้านบนเช่น UI โดยไม่ต้องเปิดเผยเลเยอร์โดเมนจริงไปยัง UI (อนุญาตการเปลี่ยนแปลง ที่จะทำให้โดเมนโดยไม่มีผลกระทบต่อ UI ตราบใดที่ DTO ไม่จำเป็นต้องเปลี่ยนแปลง)
KeithS

ความไม่แน่นอนนั้นไม่มีผลต่อการดัดแปลงหรือการคงอยู่

4
@JarrodRoberson - คุณล้อเล่นเหรอ? หากคลาสไม่เปลี่ยนรูป (ไม่สามารถเปลี่ยนได้หลังจากที่สร้างอินสแตนซ์) วิธีเดียวที่จะทำการเปลี่ยนแปลงข้อมูลในชั้นข้อมูลคือการสร้างอินสแตนซ์ใหม่ที่แสดงถึงระเบียนเดียวกัน (PK เดียวกัน) กับสมาชิกที่แตกต่างกัน ขณะที่ "กรรมวิธี" วิธีการที่ผลิตตัวอย่างใหม่สามารถทำให้มันง่ายขึ้นก็ยังคงมีขนาดใหญ่แบริ่งในการปรับเปลี่ยนและความเพียร
KeithS

1
@JarrodRoberson ฟังชุมชน คุณผิด. . ในความเป็นจริงครึ่งความคิดเห็นในคำตอบทั้งหมดนี้แสดงให้เห็นว่าเราจำเป็นต้องมีการศึกษาขั้นพื้นฐาน OO รอบ ๆ คณะกรรมการ - มันน่าขยะแขยง ..
David Cowden

5

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


1
คุณพูดอย่างนั้น แต่คุณสามารถยกตัวอย่างให้กับBarชั้นเรียนได้ไหม
Blundell

3

แบบ Builder (หรือสิ่งที่ใกล้เคียงกับมัน) อาจจะมีการใช้งานที่นี่

การมีวัตถุที่ไม่เปลี่ยนรูปนั้นเป็นสิ่งที่น่าชื่นชม แต่ความจริงก็คือด้วย Reflection ใน Java ไม่มีสิ่งใดที่ปลอดภัยอย่างแท้จริง ;-)


ฉันสามารถดูวิธีการHawaiianPizzaBuilderทำงานได้เนื่องจากค่าที่ต้องการนั้นเป็นฮาร์ดโค้ด อย่างไรก็ตามคุณจะใช้รูปแบบนี้ได้อย่างไรหากมีการดึงค่าและส่งผ่านไปยังตัวสร้าง HawaiianPizzaBuilderยังคงมี getters ทั้งหมดที่SpicyPizzaBuilderมีเพื่อให้ null เป็นไปได้ ถ้าคุณรวมนี้กับ Null Object Pattern@Jarrods ตัวอย่างโค้ดที่Barจะทำให้คุณได้คะแนน
Blundell

+1ฉันใช้ตัวสร้างในกรณีเช่นนี้ทำงานเหมือนเครื่องราง - รวมถึง แต่ไม่ จำกัด เฉพาะการตั้งค่าเริ่มต้นที่เหมาะสมแทนที่จะเป็นค่าว่างเมื่อฉันต้องการสิ่งนี้
gnat

3

จุดสำคัญที่นี่คือความแตกต่างระหว่างสิ่งที่ "บาร์"และวิธีการใช้งานในบริบทหนึ่งหรืออื่น

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

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

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

หลังสามารถแสดงโดยอินเทอร์เฟซที่แตกต่างกันสองที่ประกอบด้วยวิธีการเข้าถึงที่จำเป็น (getName (), getURL (), getDistance ()), และคลาสบาร์ควรใช้ทั้งสองอย่าง (และบางที "ระยะทาง" จะเปลี่ยนเป็น "ตำแหน่ง" และ getDistance () จะกลายเป็นการคำนวณจากตำแหน่งอื่น :-))

แต่การสร้างมีไว้สำหรับเอนทิตีบาร์และไม่ใช่สำหรับวิธีที่คุณต้องการใช้เอนทิตีนั้น: ผู้สร้างรายเดียวเขตข้อมูลทั้งหมด

แก้ไข: ฉันสามารถเขียนรหัส! :-)

public interface Place {
  String getName();
  Address getAddress();
}

public interface WebPlace extends Place {
   URL getUrl();
   Image getLogo();
}

public interface PhysicalPlace extends Place {
  Double getDistance();
  Slogon getSlogon();
}

public class Bar implements WebPlace, PhysicalPlace {
  private final String name;
  private final Address address;
  private final URL url;
  private final Image logo;
  private final Double distance;
  private final Slogon slogon;

  public Bar(String name, Address address, URL url, Image logo, Double distance, Slogon slogon) {
    this.name = name;
    this.address = address;
    this.url = url;
    this.logo = logo;
    this.distance = distance;
    this.slogon = slogon;
  }

  public String getName() { return name; }
  public Address getAddress() { return address; }
  public Double getDistance() { return distance; }
  public Slogon getSlogon() { return slogon; }
  public URL getUrl() { return url; }
  public Image getLogo() { return logo; } 
}

1

รูปแบบที่เหมาะสม

Null Object Patternสิ่งที่คุณกำลังมองหาที่มากที่สุดที่เรียกว่า หากคุณไม่ชอบชื่อที่คุณสามารถเรียกได้ว่าUndefined Value Patternป้ายกำกับที่แตกต่างกันมีความหมายเหมือนกัน Poison Pill Patternบางครั้งรูปแบบนี้จะเรียกว่า

ในทุกกรณีวัตถุนั้นจะถูกแทนที่หรือยืนอยู่เพื่อDefault Valueแทนที่null. It doesn't replace the semantic ofnull but makes it easier to work with the data model in a more predictable way becausenull` ตอนนี้ไม่ควรเป็นสถานะที่ถูกต้อง

มันเป็นรูปแบบที่คุณจองอินสแตนซ์พิเศษของคลาสที่กำหนดเพื่อแสดงnullตัวเลือกเป็นอย่างDefault Valueอื่น ด้วยวิธีนี้คุณไม่จำเป็นต้องตรวจสอบnullคุณสามารถตรวจสอบข้อมูลประจำตัวกับNullObjectอินสแตนซ์ที่คุณรู้จัก NullPointerExceptionsคุณสามารถเรียกวิธีการเกี่ยวกับมันและชอบโดยไม่ต้องกังวลเกี่ยวกับ

วิธีนี้คุณจะแทนที่การnullมอบหมายของคุณด้วยNullObjectอินสแตนซ์ตัวแทนและดำเนินการเสร็จสิ้น

การวิเคราะห์เชิงวัตถุที่เหมาะสม

วิธีนี้คุณสามารถใช้ร่วมกันInterfaceสำหรับ polymorphism และยังคงได้รับการปกป้องจากการไม่ต้องกังวลเกี่ยวกับการขาดข้อมูลในการใช้งานเฉพาะของอินเทอร์เฟซ ดังนั้นบางคนBarอาจไม่มีสถานะเว็บและบางคนอาจไม่มีข้อมูลตำแหน่งในขณะที่สร้าง Null Object Patterช่วยให้คุณสามารถระบุค่าเริ่มต้นสำหรับข้อมูลเหล่านี้ซึ่งเป็นmarkerข้อมูลที่ระบุว่าเหมือนกันไม่มีสิ่งใดให้มาที่นี่โดยไม่ต้องจัดการกับการตรวจสอบNullPointerExceptionทุกที่

การออกแบบเชิงวัตถุที่เหมาะสม

อันดับแรกมีabstractการนำไปใช้ซึ่งเป็นชุดสุดยอดของคุณลักษณะทั้งหมดที่ทั้งสองBarและใช้Clubร่วมกัน

class abstract Establishment 
{
     private final String name;
     private final Distance distance;
     private final Url url;

     public Bar(final String name, final Distance distance, final Url url)
     {
          this.name = name;
          this.distance = distance;
          this.url = url;
     }

     public Bar(final String name, final Distance distance)
     {
          this(name, distance, Url.UNKOWN_VALUE);
     }

     public Bar(final String name, final Url url)
     {
          this(name, Distance.UNKNOWN_VALUE, url);
     }

     // other code
}

จากนั้นคุณสามารถใช้คลาสย่อยของคลาสนี้Establishmentและเพิ่มเฉพาะสิ่งที่คุณต้องการสำหรับแต่ละคลาสBarและClubคลาสที่ไม่ใช้กับคลาสอื่น

วิริยะ

วัตถุตัวยึดตำแหน่งเหล่านี้หากสร้างอย่างถูกต้องสามารถเก็บไว้ในฐานข้อมูลได้อย่างโปร่งใสโดยไม่ต้องมีการจัดการเป็นพิเศษเช่นกัน

พิสูจน์ได้ในอนาคต

หากคุณตัดสินใจที่จะข้ามไปบนแบนด์วิดเจ็ต Inversion of Control / Dependency Injection รูปแบบนี้จะทำให้ง่ายต่อการฉีดวัตถุทำเครื่องหมายเหล่านี้เช่นกัน


0

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

class EstablishmentInformation {
     private final String name;

     public EstablishmentInformation(String name){
          this.name = name;
     }

     // getters
}

class EstablishmentLocationInformation {
    EstablishmentInformation establishmentInformation;
     private final Distance distance;

     public EstablishmentLocationInformation (String name, Distance distance){
          this.establishmentInformation = new EstablishmentInformation(name)
          this.distance = distance;
     }
}

class EstablishmentWebSiteInformation {
    EstablishmentInformation establishmentInformation;
     private final Url url;

     public EstablishmentWebSiteInformation(String name, Url url){
          this.establishmentInformation = new EstablishmentInformation(name)
          this.url = url;
     }
}

-1

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

class OnlineBar {
     private final String name;
     private final Url url;
     public OnlineBar(String name, Url url){
          this.name = name;
          this.url = url;
     }

     // ...
}
class PhysicalBar {
     private final String name;
     private final Distance distance;
     public PhysicalBar(String name, Distance distance){
          this.name = name;
          this.distance = distance;
     }
     //...
}

หากคุณต้องการใช้งานอย่างเท่าเทียมกันให้พิจารณาเพิ่มส่วนต่อประสานหรือใช้การสะท้อนกลับ


@David: โอ้ noes พวกเขามีเหมือนสมาชิกข้อมูลทั้งหมดหนึ่งที่เหมือนกัน เมื่อเกิดเหตุฉุกเฉิน!
DeadMG

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

1
@DeadMG นี่อาจเป็นแบบฝึกหัดในความคิดของการจัดกลุ่มค่าที่ใช้ร่วมกันไปยังวัตถุหลัก .. โซลูชันของคุณจะไม่ได้รับเครดิตเต็มถ้าคุณเสนอในบริบทนั้น
David Cowden

OP ไม่ได้ระบุความต้องการความสามารถในการทดแทนใด ๆ และอย่างที่ฉันบอกไว้คุณสามารถเพิ่มส่วนต่อประสานหรือใช้การสะท้อนหากคุณต้องการ
DeadMG

@DeadMG แต่สะท้อนเป็นเหมือนพยายามที่จะเขียน app มือถือข้ามแพลตฟอร์มโดยใช้สภาพแวดล้อมหนึ่ง - มันอาจจะทำงาน แต่ก็ไม่ถูกต้อง บทลงโทษสำหรับการเรียกใช้เมธอดที่ใช้การสะท้อนนั้นอยู่ระหว่าง 2 ถึง 50 เท่าช้ากว่าการเรียกเมธอดปกติ การไตร่ตรองนั้นไม่ได้เป็นการรักษาเลย ..
เดวิดคาวเด็น

-1

คำตอบของฉันทุกคนที่มีประเภทของปัญหานี้คือการทำลายมันลงขั้นตอนการจัดการที่

  1. ก่อนอื่นให้สร้างสองคลาสBarOneและBarTwo(หรือเรียกทั้งสองอย่างBarแต่ในแพ็คเกจอื่น)
  2. เริ่มใช้วัตถุของคุณเนื่องจากคลาสที่แยกจากกันไม่ต้องกังวลกับการทำสำเนารหัสในตอนนี้ คุณจะสังเกตเห็นเมื่อคุณข้าม (วิธีการซ้ำ) จากที่หนึ่งไปยังอีก
  3. คุณอาจพบว่าพวกเขาไม่มีส่วนเกี่ยวข้องและดังนั้นคุณควรถามตัวเองว่าพวกเขาทั้งสองเป็นคนจริงๆbarหรือไม่ถ้าไม่เปลี่ยนชื่อชั้นเรียนที่กระทำผิดต่อสิ่งที่เป็นอยู่ในปัจจุบัน
  4. หากการค้นหาเขตข้อมูลทั่วไปหรือลักษณะการทำงานของคุณคุณสามารถแยกinterfaceหรือsuperclassมีลักษณะการทำงานร่วมกันได้
  5. เมื่อคุณมีinterfaceหรือsuperclassคุณสามารถสร้างbuilderหรือfactoryเพื่อสร้าง / ดึงวัตถุการใช้งานของคุณ

(4 และ 5 เป็นคำตอบของคำถามนี้)


-2

คุณจำเป็นต้องมีชั้นฐานตัวอย่างเช่นสถานที่ซึ่งมีชื่อและที่อยู่ ตอนนี้คุณมีสองชั้นบาร์และBarPreviewขยายชั้นฐานที่ตั้ง ในแต่ละคลาสคุณจะเริ่มต้นตัวแปรสามัญระดับซุปเปอร์แล้วตัวแปรเฉพาะของคุณ:

public class Location {
    protected final String name;
    protected final String address:

    public Location (String locName, String locAddress) {
    name = locName;
    address = locAddress
    }

}

public class Bar extends Location {
    private final int dist;
    private final String slogan;

    public Bar(String barName, String barAddress,
               int distance, String barSlogan) {
    super(locName, locAddress);
    dist = distance;
    slogan = barSlogan;
    }
}

และคล้ายกับคลาส BarPreview ..

ถ้ามันทำให้คุณนอนหลับได้ดีในเวลากลางคืนแทนทุกกรณีที่อยู่ในรหัสของฉันกับAnythingYouThinkWouldBeAnAppropriateNameForAThingThatABarExtendsSuchAsFoodServicePlace - FFS


OP ต้องการเช่นที่จะไม่เปลี่ยนรูปfinalนั่นหมายความว่าทุกอย่างจะต้องมี

1
สิ่งนี้สามารถใช้งานได้คุณต้องไปfinalที่ช่อง @David Barไม่ควรextend Locationแม้ว่าจะไม่สมเหตุสมผล บางทีBar extends BaseBarและBarPreview extends BaseBarชื่อเหล่านี้อาจฟังดูไม่ดีนัก แต่ฉันก็หวังว่าจะมีอะไรที่หรูหรากว่านี้อีกแล้ว
Blundell

@JarrodRoberson ฉันแค่วาดมันให้เขา .. แค่เพิ่มสุดท้ายให้มันไม่เปลี่ยนรูป มันไม่ใช่เรื่องง่าย .. ปัญหาพื้นฐานของคำถาม OP คือเขาไม่รู้ว่าจะมีคลาสพื้นฐานและคลาสแยกสองคลาสที่ขยายคลาสฐานได้อย่างไร ฉันแค่บอกรายละเอียด
David Cowden

@Blundell คุณกำลังพูดถึงอะไรในโลก? บาร์ เป็นสถานที่ตั้ง เพียงแค่แทนที่ตำแหน่งของฉันด้วย BaseBar ของคุณและมันก็เป็นสิ่งเดียวกัน .. คุณรู้หรือไม่ว่าเมื่อชั้นหนึ่งขยายชั้นเรียนอีกชั้นหนึ่งชั้นที่ขยายออกไปนั้นไม่จำเป็นต้องตั้งชื่อฐาน [ClassThatWillExtend] ใช่ไหม?
David Cowden

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