ค้นหาเว็บไซต์

typescript - เป็นไปได้ไหมที่จะแยกแบบแผน singleton ออกจากคลาสเอง?


การทำงานกับ typescript/javascript ฉันได้สร้างคอลเลคชันของ singleton

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

ดังนั้นคำถามของฉันคือ เป็นไปได้ไหมที่จะนำพฤติกรรมแบบซิงเกิลตันไปใช้กับชุดของคลาส/อ็อบเจ็กต์อย่างสง่างาม

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

class Car {
  /* Singleton Implementation Start */
  private static _instance: Car;

  private constructor() {}

  public static getInstance(): Car {
    if (!Car._instance) {
      Car._instance = new Car();
    }
    return Car._instance;
  }
  /* Singleton Implementation End */

  private _name = "Audi"
  private _color = 'red';
  private _maxSpeed = 150;

  drive(){
    console.log(`WOW! You are riding your cool ${this._color} ${this._name} at ${150} kmh!` )
  }

  paint(color: string){
    this._color = color;
  }
}

class Plane {
  /* Singleton Implementation Start */
  private static _instance: Plane;

  private constructor() {}

  public static getInstance(): Plane {
    if (!Plane._instance) {
      Plane._instance = new Plane();
    }
    return Plane._instance;
  }
  /* Singleton Implementation End */

  private _motors = 4;
  private _maxSpeed = 550;

  fly(){
    console.log(`WOW! You are flying your plane with roaring ${_motors} motors at ${150} kmh!` )
  }
}

คำตอบ #1

ถ้าเราสร้างฟังก์ชันโรงงานที่รับชนิดทั่วไป:

function Singleton<T>() {
    return class Singleton {
        static instance: T; // must be public

        protected constructor() {}

        public static getInstance(): T {
            if (!this.instance) this.instance = new this() as T;

            return this.instance;
        }
    }
}

แล้วเราสามารถขยายคลาสที่ส่งกลับมาและให้ประเภททั่วไปเป็นคลาสนั้นเอง:

class Car extends Singleton<Car>() {
  private _name = "Audi"
  private _color = 'red';
  private _maxSpeed = 150;

  drive(){
    console.log(`WOW! You are riding your cool ${this._color} ${this._name} at ${150} kmh!` )
  }

  paint(color: string){
    this._color = color;
  }
}

สิ่งนี้ต้องทำด้วยฟังก์ชันเนื่องจากสมาชิกแบบคงที่ไม่สามารถอ้างอิงพารามิเตอร์ชนิดของคลาสได้ นอกจากนี้ ข้อเสียคือคุณไม่สามารถมีสมาชิกแบบส่วนตัวหรือป้องกันได้

สนามเด็กเล่น

บทความที่เกี่ยวข้อง