如何使用AI辅助开发

自从踏上AI辅助开发这条不归路,就回不了头,只能勇往直前!就算是简单的智能提示、补充代码、自动多语言补全等功能,就已经让你离不开它,更何况强大的代码生成成功。如果还没有开始使用AI辅助开发,那么赶快为自己的开发工具安装一个免费的AI助手,基本上目前流行的开发工具都会有对应的免费的辅助AI插件。

对于第一次使用AI辅助开发的开发者,记住一点:给出的问题,也就是需求,越详细,AI给的代码就越完整,功能也完善。本文将通过一个实例来探讨如何让AI助手生成满意的代码。

本文的开发环境为vs code,AI助手将使用Fitten Code扩展。安装完Fitten Code后,会在主侧边栏显示一个Fitten Code的图标,切换到Fitten Code,在底部会有一个输入框,输入想要的问题就能生成所需的代码。

现在,在输入框输入“使用Typescript创建一个仓储用来获取远程数据”并按回车发送,将会看到以下返回信息:
返回一
返回二
从生成的Repository类可以看到,已经生成了getAllgetById方法,并建议添加createupdatedelete 等方法。当然,你应该不会满足于此,获取数据时,分页、过滤和高级过滤等等功能还没添加,建议的三个方法也生成,这时候,就需要列一个详细的需求给它,让它生成更完整的代码。

下面在输入框输入以下需求:

使用Typescript创建一个仓储类用来获取远程数据并具有以下功能:
* 获取传递给构造函数的配置项pageSizes的第一数据作为当前的pageSize,并添加setPageSize方法来设置设置当前的pageSize,要验证设置的pageSize是否在pageSizes中,pageSize改变后,重新加载数据。添加getPageSize方法来获取当前的pageSize。
*  添加setPage方法来设置当前页,当前页改变后,重新加载数据。添加getPage方法来获取当前页,
* 添加filter方法来执行数据过滤
* 添加sort方法来对数据进行排序
* 添加search方法来对数据进行高级过滤
* 添加getTotal方法来获取记录总数
* 添加getPages方法来获取总页数
* 添加load方法来获取远程数据,在执行远程加载前,如果在构造函数中传入了beforeLoad函数,则先执行beforeLoad,如果返回false,则不执行数据加载。如果可以加载数据,则先调用getParams方法整合分页、过滤、高级过滤等数据,为加载数据提供参数。在数据加载后,如果从构造函数中传入了afterLoad函数,则执行afterLoad函数,然后触发laod事件。
* 添加create方法用来保存新记录
* 添加update方法用来更新记录
* 添加delete方法用来删除记录
* 添加一个方法用来获取单一数据

等待一会就会得到以下代码:

import axios, { AxiosResponse } from 'axios';

interface RemoteData {
  id: number;
  name: string;
  // 其他字段...
}

interface RepositoryConfig {
  baseUrl: string;
  pageSizes: number[];
  beforeLoad?: () => boolean;
  afterLoad?: (data: RemoteData[]) => void;
}

class AdvancedRepository {
  private baseUrl: string;
  private pageSizes: number[];
  private pageSize: number;
  private page: number;
  private total: number;
  private data: RemoteData[];
  private beforeLoad?: () => boolean;
  private afterLoad?: (data: RemoteData[]) => void;

  constructor(config: RepositoryConfig) {
    this.baseUrl = config.baseUrl;
    this.pageSizes = config.pageSizes;
    this.pageSize = config.pageSizes[0];
    this.page = 1;
    this.total = 0;
    this.data = [];
    this.beforeLoad = config.beforeLoad;
    this.afterLoad = config.afterLoad;
  }

  public setPageSize(size: number): void {
    if (!this.pageSizes.includes(size)) {
      throw new Error('Invalid page size');
    }
    this.pageSize = size;
    this.load();
  }

  public getPageSize(): number {
    return this.pageSize;
  }

  public setPage(page: number): void {
    this.page = page;
    this.load();
  }

  public getPage(): number {
    return this.page;
  }

  public filter(filterFn: (item: RemoteData) => boolean): void {
    this.data = this.data.filter(filterFn);
  }

  public sort(sortFn: (a: RemoteData, b: RemoteData) => number): void {
    this.data.sort(sortFn);
  }

  public search(searchFn: (item: RemoteData) => boolean): void {
    this.data = this.data.filter(searchFn);
  }

  public getTotal(): number {
    return this.total;
  }

  public getPages(): number {
    return Math.ceil(this.total / this.pageSize);
  }

  public async load(): Promise<void> {
    if (this.beforeLoad && !this.beforeLoad()) {
      return;
    }

    const params = this.getParams();
    try {
      const response: AxiosResponse<{ data: RemoteData[]; total: number }> = await axios.get(`${this.baseUrl}/data`, { params });
      this.data = response.data.data;
      this.total = response.data.total;
      if (this.afterLoad) {
        this.afterLoad(this.data);
      }
      // 触发load事件
    } catch (error) {
      console.error('Error fetching data:', error);
      throw error;
    }
  }

  private getParams(): any {
    return {
      page: this.page,
      pageSize: this.pageSize,
      // 其他参数...
    };
  }

  public async create(data: RemoteData): Promise<RemoteData> {
    try {
      const response: AxiosResponse<RemoteData> = await axios.post(`${this.baseUrl}/data`, data);
      this.load();
      return response.data;
    } catch (error) {
      console.error('Error creating data:', error);
      throw error;
    }
  }

  public async update(id: number, data: RemoteData): Promise<RemoteData> {
    try {
      const response: AxiosResponse<RemoteData> = await axios.put(`${this.baseUrl}/data/${id}`, data);
      this.load();
      return response.data;
    } catch (error) {
      console.error('Error updating data:', error);
      throw error;
    }
  }

  public async delete(id: number): Promise<void> {
    try {
      await axios.delete(`${this.baseUrl}/data/${id}`);
      this.load();
    } catch (error) {
      console.error('Error deleting data:', error);
      throw error;
    }
  }

  public async getById(id: number): Promise<RemoteData> {
    try {
      const response: AxiosResponse<RemoteData> = await axios.get(`${this.baseUrl}/data/${id}`);
      return response.data;
    } catch (error) {
      console.error(`Error fetching data with id ${id}:`, error);
      throw error;
    }
  }
}

// 使用示例
const repo = new AdvancedRepository({
  baseUrl: 'https://api.example.com',
  pageSizes: [10, 20, 50],
  beforeLoad: () => {
    // 执行一些预加载逻辑
    return true;
  },
  afterLoad: (data) => {
    console.log('Data loaded:', data);
  }
});

repo.load().then(() => {
  console.log('Data loaded');
}).catch(error => {
  console.error('Error:', error);
});

虽然代码不尽人意,但起码已具雏形。这时候你的选择可以是重新组织需求,再次生成,或者选择全部代码,在选择代码上单击鼠标右键,在右键菜单中选择Fitten Code - 开始聊天,然后在输入框中输入:

在filter方法中,用filter属性记录当前过滤值,然后重新调用load方法。sort和search方法与fitler方法类似。在数据加载后,从data中获取记录, 如果有afterLoad函数,则将afterLoad函数返回值作为data属性的值,在更新total后,根据pageSize重新计算pages。

以下是返回的代码:

import axios, { AxiosResponse } from 'axios';

interface RemoteData {
  id: number;
  name: string;
  // 其他字段...
}

interface RepositoryConfig {
  baseUrl: string;
  pageSizes: number[];
  beforeLoad?: () => boolean;
  afterLoad?: (data: RemoteData[]) => void;
}

class Repository {
  private baseUrl: string;
  private pageSizes: number[];
  private pageSize: number;
  private page: number;
  private total: number;
  private data: RemoteData[];
  private beforeLoad?: () => boolean;
  private afterLoad?: (data: RemoteData[]) => void;
  private filterFn?: (item: RemoteData) => boolean;
  private sortFn?: (a: RemoteData, b: RemoteData) => number;
  private searchFn?: (item: RemoteData) => boolean;

  constructor(config: RepositoryConfig) {
    this.baseUrl = config.baseUrl;
    this.pageSizes = config.pageSizes;
    this.pageSize = config.pageSizes[0];
    this.page = 1;
    this.total = 0;
    this.data = [];
    this.beforeLoad = config.beforeLoad;
    this.afterLoad = config.afterLoad;
  }

  public setPageSize(size: number): void {
    if (!this.pageSizes.includes(size)) {
      throw new Error('Invalid page size');
    }
    this.pageSize = size;
    this.load();
  }

  public getPageSize(): number {
    return this.pageSize;
  }

  public setPage(page: number): void {
    this.page = page;
    this.load();
  }

  public getPage(): number {
    return this.page;
  }

  public filter(filterFn: (item: RemoteData) => boolean): void {
    this.filterFn = filterFn;
    this.load();
  }

  public sort(sortFn: (a: RemoteData, b: RemoteData) => number): void {
    this.sortFn = sortFn;
    this.load();
  }

  public search(searchFn: (item: RemoteData) => boolean): void {
    this.searchFn = searchFn;
    this.load();
  }

  public getTotal(): number {
    return this.total;
  }

  public getPages(): number {
    return Math.ceil(this.total / this.pageSize);
  }

  public async load(): Promise<void> {
    if (this.beforeLoad && !this.beforeLoad()) {
      return;
    }

    const params = this.getParams();
    try {
      const response: AxiosResponse<{ data: RemoteData[]; total: number }> = await axios.get(`${this.baseUrl}/data`, { params });
      let data = response.data.data;
      if (this.filterFn) {
        data = data.filter(this.filterFn);
      }
      if (this.sortFn) {
        data.sort(this.sortFn);
      }
      if (this.searchFn) {
        data = data.filter(this.searchFn);
      }
      this.data = data;
      this.total = response.data.total;
      if (this.afterLoad) {
        this.data = this.afterLoad(this.data);
      }
    } catch (error) {
      console.error('Error fetching data:', error);
      throw error;
    }
  }

  private getParams(): any {
    return {
      page: this.page,
      pageSize: this.pageSize,
      // 其他参数...
    };
  }

  public async create(data: RemoteData): Promise<RemoteData> {
    try {
      const response: AxiosResponse<RemoteData> = await axios.post(`${this.baseUrl}/data`, data);
      this.load();
      return response.data;
    } catch (error) {
      console.error('Error creating data:', error);
      throw error;
    }
  }

  public async update(id: number, data: RemoteData): Promise<RemoteData> {
    try {
      const response: AxiosResponse<RemoteData> = await axios.put(`${this.baseUrl}/data/${id}`, data);
      this.load();
      return response.data;
    } catch (error) {
      console.error('Error updating data:', error);
      throw error;
    }
  }

  public async delete(id: number): Promise<void> {
    try {
      await axios.delete(`${this.baseUrl}/data/${id}`);
      this.load();
    } catch (error) {
      console.error('Error deleting data:', error);
      throw error;
    }
  }

  public async getById(id: number): Promise<RemoteData> {
    try {
      const response: AxiosResponse<RemoteData> = await axios.get(`${this.baseUrl}/data/${id}`);
      return response.data;
    } catch (error) {
      console.error(`Error fetching data with id ${id}:`, error);
      throw error;
    }
  }
}



从返回的代码可以看到,AI还是没完全领会,filter等是作为远程参数去获取数据,还是只做了本地过滤,这也只能怪自己没把需求说清楚。重复选择代码,开始聊天的操作并输入:

在getParams中整合filter、sort、search等信息作为远程查询的参数,而不是对返回的数据执行过滤和排序

以下是更新好的代码:

import axios, { AxiosResponse } from 'axios';

interface RemoteData {
  id: number;
  name: string;
  // 其他字段...
}

interface RepositoryConfig {
  baseUrl: string;
  pageSizes: number[];
  beforeLoad?: () => boolean;
  afterLoad?: (data: RemoteData[]) => void;
}

class Repository {
  private baseUrl: string;
  private pageSizes: number[];
  private pageSize: number;
  private page: number;
  private total: number;
  private data: RemoteData[];
  private beforeLoad?: () => boolean;
  private afterLoad?: (data: RemoteData[]) => void;
  private filterParams?: any;
  private sortParams?: any;
  private searchParams?: any;

  constructor(config: RepositoryConfig) {
    this.baseUrl = config.baseUrl;
    this.pageSizes = config.pageSizes;
    this.pageSize = config.pageSizes[0];
    this.page = 1;
    this.total = 0;
    this.data = [];
    this.beforeLoad = config.beforeLoad;
    this.afterLoad = config.afterLoad;
  }

  public setPageSize(size: number): void {
    if (!this.pageSizes.includes(size)) {
      throw new Error('Invalid page size');
    }
    this.pageSize = size;
    this.load();
  }

  public getPageSize(): number {
    return this.pageSize;
  }

  public setPage(page: number): void {
    this.page = page;
    this.load();
  }

  public getPage(): number {
    return this.page;
  }

  public filter(filterParams: any): void {
    this.filterParams = filterParams;
    this.load();
  }

  public sort(sortParams: any): void {
    this.sortParams = sortParams;
    this.load();
  }

  public search(searchParams: any): void {
    this.searchParams = searchParams;
    this.load();
  }

  public getTotal(): number {
    return this.total;
  }

  public getPages(): number {
    return Math.ceil(this.total / this.pageSize);
  }

  public async load(): Promise<void> {
    if (this.beforeLoad && !this.beforeLoad()) {
      return;
    }

    const params = this.getParams();
    try {
      const response: AxiosResponse<{ data: RemoteData[]; total: number }> = await axios.get(`${this.baseUrl}/data`, { params });
      this.data = response.data.data;
      this.total = response.data.total;
      if (this.afterLoad) {
        this.data = this.afterLoad(this.data);
      }
    } catch (error) {
      console.error('Error fetching data:', error);
      throw error;
    }
  }

  private getParams(): any {
    const params: any = {
      page: this.page,
      pageSize: this.pageSize,
      // 其他参数...
    };

    if (this.filterParams) {
      Object.assign(params, this.filterParams);
    }
    if (this.sortParams) {
      Object.assign(params, this.sortParams);
    }
    if (this.searchParams) {
      Object.assign(params, this.searchParams);
    }

    return params;
  }

  public async create(data: RemoteData): Promise<RemoteData> {
    try {
      const response: AxiosResponse<RemoteData> = await axios.post(`${this.baseUrl}/data`, data);
      this.load();
      return response.data;
    } catch (error) {
      console.error('Error creating data:', error);
      throw error;
    }
  }

  public async update(id: number, data: RemoteData): Promise<RemoteData> {
    try {
      const response: AxiosResponse<RemoteData> = await axios.put(`${this.baseUrl}/data/${id}`, data);
      this.load();
      return response.data;
    } catch (error) {
      console.error('Error updating data:', error);
      throw error;
    }
  }

  public async delete(id: number): Promise<void> {
    try {
      await axios.delete(`${this.baseUrl}/data/${id}`);
      this.load();
    } catch (error) {
      console.error('Error deleting data:', error);
      throw error;
    }
  }

  public async getById(id: number): Promise<RemoteData> {
    try {
      const response: AxiosResponse<RemoteData> = await axios.get(`${this.baseUrl}/data/${id}`);
      return response.data;
    } catch (error) {
      console.error(`Error fetching data with id ${id}:`, error);
      throw error;
    }
  }
}

如果觉得代码还是不太满意,可以继续重复以下操作更改代码直到满意,还可以选择代码后,在选择代码上单击鼠标右键选择Fitter Code - 优化代码,让它自己去优化代码,返回结果如下:

import axios, { AxiosResponse } from 'axios';

interface RemoteData {
  id: number;
  name: string;
  // 其他字段...
}

interface RepositoryConfig {
  baseUrl: string;
  pageSizes: number[];
  beforeLoad?: () => boolean;
  afterLoad?: (data: RemoteData[]) => void;
}

class Repository {
  private baseUrl: string;
  private pageSizes: number[];
  private pageSize: number;
  private page: number;
  private total: number;
  private data: RemoteData[];
  private beforeLoad?: () => boolean;
  private afterLoad?: (data: RemoteData[]) => void;
  private filterParams?: any;
  private sortParams?: any;
  private searchParams?: any;

  constructor(config: RepositoryConfig) {
    this.baseUrl = config.baseUrl;
    this.pageSizes = config.pageSizes;
    this.pageSize = config.pageSizes[0];
    this.page = 1;
    this.total = 0;
    this.data = [];
    this.beforeLoad = config.beforeLoad;
    this.afterLoad = config.afterLoad;
  }

  public setPageSize(size: number): void {
    if (!this.pageSizes.includes(size)) {
      throw new Error('Invalid page size');
    }
    this.pageSize = size;
    this.load();
  }

  public getPageSize(): number {
    return this.pageSize;
  }

  public setPage(page: number): void {
    this.page = page;
    this.load();
  }

  public getPage(): number {
    return this.page;
  }

  public filter(filterParams: any): void {
    this.filterParams = filterParams;
    this.load();
  }

  public sort(sortParams: any): void {
    this.sortParams = sortParams;
    this.load();
  }

  public search(searchParams: any): void {
    this.searchParams = searchParams;
    this.load();
  }

  public getTotal(): number {
    return this.total;
  }

  public getPages(): number {
    return Math.ceil(this.total / this.pageSize);
  }

  public async load(): Promise<void> {
    if (this.beforeLoad && !this.beforeLoad()) {
      return;
    }

    const params = this.getParams();
    try {
      const response: AxiosResponse<{ data: RemoteData[]; total: number }> = await axios.get(`${this.baseUrl}/data`, { params });
      this.data = response.data.data;
      this.total = response.data.total;
      if (this.afterLoad) {
        this.data = this.afterLoad(this.data);
      }
    } catch (error) {
      console.error('Error fetching data:', error);
      throw error;
    }
  }

  private getParams(): any {
    const params: any = {
      page: this.page,
      pageSize: this.pageSize,
      // 其他参数...
    };

    if (this.filterParams) {
      Object.assign(params, this.filterParams);
    }
    if (this.sortParams) {
      Object.assign(params, this.sortParams);
    }
    if (this.searchParams) {
      Object.assign(params, this.searchParams);
    }

    return params;
  }

  public async create(data: RemoteData): Promise<RemoteData> {
    try {
      const response: AxiosResponse<RemoteData> = await axios.post(`${this.baseUrl}/data`, data);
      this.load();
      return response.data;
    } catch (error) {
      console.error('Error creating data:', error);
      throw error;
    }
  }

  public async update(id: number, data: RemoteData): Promise<RemoteData> {
    try {
      const response: AxiosResponse<RemoteData> = await axios.put(`${this.baseUrl}/data/${id}`, data);
      this.load();
      return response.data;
    } catch (error) {
      console.error('Error updating data:', error);
      throw error;
    }
  }

  public async delete(id: number): Promise<void> {
    try {
      await axios.delete(`${this.baseUrl}/data/${id}`);
      this.load();
    } catch (error) {
      console.error('Error deleting data:', error);
      throw error;
    }
  }

  public async getById(id: number): Promise<RemoteData> {
    try {
      const response: AxiosResponse<RemoteData> = await axios.get(`${this.baseUrl}/data/${id}`);
      return response.data;
    } catch (error) {
      console.error(`Error fetching data with id ${id}:`, error);
      throw error;
    }
  }
}

在通过手动和互动等方法完成代码后,就可以让AI帮忙生成完整的单元测试代码,获得最终的代码了。

从以上的探讨过程可以看到,AI还不能做到尽善尽美,但已经可以大大提高开发效率了。不过要注意的是,有时候AI会陷入死循环,譬如说A这样会导致问题B,然后它去改,问题B解决了,但会出现A的问题没有解决,然后它就进入死循环,A和B来回切换,这时候,就要换个思路了,不要和它继续纠缠下去,不然会很累。可行的办法有换个解决问题的思路,或者找其他免费的AI辅助,如千义通问等等,这些AI各具特色,有自己擅长的东西,多问几个,会获得更精准的解决方案。笔者觉得更重要的是,提高自己的设计能力和需求讲述能力,将可大大释放AI的能力。

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值