ES6 modules and inheritance

后端 未结 1 691
抹茶落季
抹茶落季 2021-02-14 23:10

I have the following JavaScript files:

src/js/classes/Lexus.js:

import {Car} from \'src/js/classes/Car\';

export class Lexus extends Ca         


        
相关标签:
1条回答
  • 2021-02-14 23:57

    Typically, you want to not have circular dependencies like this. Circular dependencies at the best of times, break everything and don't compile (or transpile). Circular dependencies at the worst of times, cause merge and versioning conflicts, cause code that's really hard to discern, look like they're working just fine, until they stop, with some terrible bug caused by some terrible state assumptions.

    Your solution (if you are dead-set on this form of inheritance) is going to be to extract Car into its own file/class, which can be imported separately, and to have the Factory be separate from the class.

    Which, in English makes complete sense.
    Cars don't construct Lexuses (Lexi?).

    Additionally, if you did want to keep this (not a great idea), then you should have a register method, not a hard-coded solution, whereby you register "Lexus" and the function which makes a new Lexus.

    import Car from "./car";
    class Lexus extends Car {
      constructor () {
        super("Lexus");
      }
      // starting to look like a bad idea
      static make () {
        return Car.make("Lexus");
      }
      // starting to look worse
      static register () {
        /* this register method does nothing, so that Lexus can't make other cars... */
      }
    }
    
    Car.register("Lexus", () => new Lexus());
    
    export default Lexus;
    

    It gets worse, but this is already plenty bad.

    If you go the other route:

    // carfactory.js
    
    const carTypes = new Map();
    class CarFactory {
      static register (name, implementation) {
        carTypes.set(name, implementation);
        return CarFactory;
      }
      static make (name) {
        const makeCar = carTypes.get(name);
        return makeCar();
      }
    
      register (name, implementation) {
        CarFactory.register(name, implementation);
        return this;
      }
      make (name) { return CarFactory.make(name); }
    }
    
    export default CarFactory;
    
    
    // index.js
    import Car from "./classes/car";
    import Lexus from "./classes/lexus";
    
    import CarFactory from "./factories/car";
    
    CarFactory
      .register("Lexus", () => new Lexus())
      .register("Bentley", () => new Bentley());
    
    init( CarFactory );
    
    function init (Car) {
      const lexus = Car.make("Lexus");
    }
    

    Now, no classes need to know about things they shouldn't have to.

    0 讨论(0)
提交回复
热议问题