TypeScript类,每个实例中未使用方法

问题描述 投票:0回答:1

我有一个TypeScript类,它正在创建ZMQ总线通信的基础。我首先想做一个通用类,可以根据需要实例化许多时间。但是现在,我需要制作更多的实例,这些实例不完全适合我制作的一般类。实际上,唯一的区别是在这些新实例中,从不使用request方法,具体取决于type。因此,是否可以保留相同的通用类,但在不需要时忽略request方法?

let zmq = require("zeromq")

class ZMQBus {
    socket:any
    port:number

    constructor(type:string, port:number) {
        this.socket = zmq.socket(type)
        this.port   = port
    }

    open(): void {
        this.socket.connect("tcp://localhost:" + this.port)

        this.socket.on("message", function(reply) {
            console.log("Received reply : " + reply.toString());
        })
    }

    request(msg:any): void {
        this.socket.send(msg);
    }

    close(): void {
        this.socket.close();
    }
}
typescript zeromq
1个回答
0
投票

我知道你说过你想避免两个类,因为你不想暗示这两个类是不同的。该请求在某些情况下不重要,不会使其有害。您仍然可以将单个类与request的单个实现一起使用,仅在需要时使用它。如果确实需要规定request不存在,则必须创建一个单独的类型。您可以通过使用工厂模式和条件类型在语义上实现所需的内容,而无需任何反模式]

type ZmqTypes = "REQUEST" | "NOREQUEST";

interface ZMQBus {
  open: () => void;
  close: () => void;
  request?: (msg: any) => void;
  type: ZmqTypes;
  port: number;
}

interface ZMQBusR extends ZMQBus {
  request: (msg: any) => void;
}

interface ZMQBusNoR extends Omit<ZMQBus, "request"> {}

class GenericZMQBus implements ZMQBus {
    socket:any
    port:number

    constructor(type:string, port:number) {
        this.socket = zmq.socket(type)
        this.port   = port
    }

    open(): void {
        this.socket.connect("tcp://localhost:" + this.port)

        this.socket.on("message", function(reply : any) {
            console.log("Received reply : " + reply.toString());
        })
    }

    close(): void {
        this.socket.close();
    }
}

class ZMQBusWithRequest extends GenericZMQBus implements ZMQBusR {
  request(msg : any) {
    console.log(msg);
  }
}

function createZMQBus<T extends ZmqTypes>(type: T, port: number) : T extends "REQUEST" ? ZMQBusR : ZMQBusNoR {
  if (type === "REQUEST") { 
    return new ZMQBusWithRequest(type, port) as unknown as T extends "REQUEST" ? ZMQBusR : ZMQBusNoR;
  }
  return new GenericZMQBus(type, port) as unknown as T extends "REQUEST" ? ZMQBusR : ZMQBusNoR;
}

const zmqObj = createZMQBus("REQUEST", 999);
const zmqObj1 = createZMQBus("NOREQUEST", 999);

zmqObj.request('hello');
zmqObj1.request('error'); // is an error

您仍然具有使用严格类型系统的多个类和接口,但是创建这些对象的单一方法暗示着一个一致的目的,即使不是一致的实现。并且由于两者都扩展了单个通用接口,因此您可以将任一类型作为单个ZMQType进行传递。您只需要确保在尝试使用request方法之前,检查其是否正确存在。

function testZMQImplementation(z: ZMQBus) {
  if (z.request) {
    z.request('testing')
  }
}

testZMQImplementation(zmqObj);
testZMQImplementation(zmqObj1);
© www.soinside.com 2019 - 2024. All rights reserved.