如何在typescript中使用抽象类

时间:2017-12-18 22:01:28

标签: javascript reactjs typescript

我正在尝试将以下示例移植(以简化方式)到打字稿,因为我想在打字稿中演示抽象工厂模式。

https://gerardnico.com/wiki/lang/java/dao

到目前为止,我创建的代码如下(仅限结构)

func extractTextFromImage(_ image: CGImage) {

    let bitmapRep = NSBitmapImageRep(cgImage: image)
    let imageData = bitmapRep.representation(using: NSBitmapImageRep.FileType.jpeg, properties: [:])! as Data
    let imageString = imageData.base64EncodedString(options: .endLineWithCarriageReturn)

    let url = URL(string: "https://api.ocr.space/parse/image")!

    let session = URLSession.shared
    var request = URLRequest(url: url)
    request.httpMethod = "POST"

    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    request.addValue("application/json", forHTTPHeaderField: "Accept")
    request.addValue("6ea787d56088957", forHTTPHeaderField: "apikey")

    var parameters = ["base64image": [ "content_type": "image/jpeg", "base64": imageString]]

    do {
        let jsonData = try JSONSerialization.data(withJSONObject: parameters, options: [])
        let theJSONText = String(data: jsonData, encoding: String.Encoding.utf8)
        print("JSON string = \(theJSONText)")
        request.httpBody = jsonData
    } catch {
        print(error.localizedDescription)
        print("ERROR: Could not convert dictionary to JSON")
        return
    }

    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    request.addValue("6ea787d56088957", forHTTPHeaderField: "apikey")

    let task: URLSessionDataTask = session.dataTask(with: request, completionHandler: { (data: Data?, response: URLResponse?, error: Error?) -> Void in

        if let response = response {
            print("RESPONSE: ", response)
        } else {
            print("ERROR: No response")
        }

        if let error = error {
            print("ERROR: ", error)
        } else {
            print("No error")
        }

        do {

            let dictionary = try JSONSerialization.jsonObject(with: data!, options: []) as! [String: Any]

            for (key, value) in dictionary {
                print("Key: ", key)
                print("Value: ", value)
            }

            if let parsedResults = dictionary["ParsedResults"] as? [[String: Any]] {
                if let parsedResult = parsedResults.first {
                    if let parsedText = parsedResult["ParsedText"] as? String {
                        print("PARSED TEXT ", parsedText)
                    } else {
                        print("ERROR: Could not read parsedText")
                    }
                } else {
                    print("ERROR: Could not read first element of parsedResult")
                }
            } else {
                print("ERROR: Could not read parsedResult")
            }

        } catch let error {
            print("ERROR: Could not serialize jSON Data: \(error.localizedDescription)")
        }
    })
    task.resume()
}

代码编译,但是我在如何使用抽象类方面存在问题,来自上述代码的客户端或调用者,这是一个SPFx REACT组件

export default class Customer{
    public id: string;
    public firstName: string;
    public lastName: string;
}


import Customer from "./Customer";

export default interface ICustomerDAO{
    insertCustomer(): number;
    deleteCustomer(): boolean;
    findCustomer(): Customer;
    updateCustomer(): boolean;
    listCustomers(): Customer[];
}


import CustomerDAO from "./ICustomerDAO";
import SharepointListDAOFactory from "./SharepointListDAOFactory";
import JsonDAOFactory from "./JsonDAOFactory";


export default abstract class DAOFactory{
    public static SHAREPOINTLIST: number = 1;
    public static REMOTEJSON : number = 2;

    public abstract getCustomerDAO(): CustomerDAO;

    public  getDAOFactory(whichFactory: number): DAOFactory {

      switch (whichFactory) {
        case 1: 
            return new SharepointListDAOFactory();
        case 2: 
            return new JsonDAOFactory();      
        default  : 
            return null;
      }
    }
}


import DAOFactory from "./DAOFactory";
import ICustomerDAO from "./ICustomerDAO";
import JsonCustomerDAO from "./JsonCustomerDAO";


export default class JsonDAOFactory extends DAOFactory{
    getCustomerDAO(): ICustomerDAO{
        return new JsonCustomerDAO();
    }
}

import DAOFactory from "./DAOFactory";
import ICustomerDAO from "./ICustomerDAO";
import SharepointCustomerDao from "./SharepointCustomerDAO";

export default class SharepointListDAOFactory extends DAOFactory{

    getCustomerDAO(): ICustomerDAO{
        return new SharepointCustomerDao();
    }
}

import ICustomerDAO from "./ICustomerDAO";
import Customer from "./Customer";

//actual implementation
export default class JsonCustomerDAO implements ICustomerDAO{

    public insertCustomer(): number{
        return 1;
    }

    public deleteCustomer(): boolean{
        return true;
    }

    public findCustomer(): Customer{
        return new Customer();
    }

    public updateCustomer(): boolean{
        return true;
    }

    public listCustomers(): Customer[]{
        let c1= new Customer();
        let c2= new Customer();
        let list: Array<Customer> = [c1, c2 ];
        return list;
    } 
}

import ICustomerDAO from "./ICustomerDAO";
import Customer from "./Customer";

//actual implementations
export default class SharepointCustomerDao implements ICustomerDAO{

    public insertCustomer(): number{
        return 1;
    }

    public deleteCustomer(): boolean{
        return true;
    }

    public findCustomer(): Customer{
        return new Customer();
    }

    public updateCustomer(): boolean{
        return true;
    }

    public listCustomers(): Customer[]{
        let c1= new Customer();
        let c2= new Customer();
        let list: Array<Customer> = [c1, c2 ];
        return list;
    } 
}

我不确定语法或如何将这些行转换为typescript

import * as React from 'react';
import styles from './TypescriptDesignPatterns02AbstractFactory.module.scss';
import { ITypescriptDesignPatterns02AbstractFactoryProps } from './ITypescriptDesignPatterns02AbstractFactoryProps';
import { escape } from '@microsoft/sp-lodash-subset';
import { ITypescriptDesignPatterns02AbstractFactoryState } from './ITypescriptDesignPatterns02AbstractFactoryState';
import SharepointListDAOFactory from './Factory/SharepointListDAOFactory';
import DAOFactory from './Factory/DAOFactory';

export default class TypescriptDesignPatterns02AbstractFactory extends React.Component<ITypescriptDesignPatterns02AbstractFactoryProps, ITypescriptDesignPatterns02AbstractFactoryState> {
  constructor(props: ITypescriptDesignPatterns02AbstractFactoryProps, state: ITypescriptDesignPatterns02AbstractFactoryState) {
    super(props);
    this.setInitialState();
  }

  public render(): React.ReactElement<ITypescriptDesignPatterns02AbstractFactoryProps> {
    switch(this.props.datasource) {
      case "Sharepoint":
        let sharepointlistdaofactory: SharepointListDAOFactory =   DAOFactory.getDAOFactory(1);



        break;
      case "JSON":
        break;
    }
    return null;
  }

  public setInitialState(): void {
    this.state = {
      items: []
    };
  }



}

1 个答案:

答案 0 :(得分:1)

目前,您的代码需要DAOFactory的实例化才能访问getDAOFactory方法:

const daoFactory = new DAOFactory;

但是你不能这样做,因为DAOFactory是抽象的。

相反,工厂函数不需要是对象方法 - 它可以是类方法(静态),甚至只是一个函数。

const getDAOFactory = (whichFactory: number): DAOFactory => {
  switch (whichFactory) {
    case 1: 
        return new SharepointListDAOFactory();
    case 2: 
        return new JsonDAOFactory();      
    default  : 
        return null;
  }
}

现在你可以调用OracleDbFactory = getDAOFactory(DAOFactory.DAOORACLEDB);(类型是从函数的返回类型隐式的)。

我确实想知道为什么你需要这个额外的抽象层。似乎像custDao = getDao(DaoTypes.Customer)这样的东西就足够了。