Java 开发者用 python 来践行面向对象编程 (第五章 面向对象编程)

Java 开发者用 python 来践行面向对象编程 (第五章 面向对象编程)

本篇是如何写代码的系列文章。距离上一篇,已经过去快四个月,最近有了一些灵感和想法,于是想把这些点写成文章记录下来。

一、开篇感想

前段时间的一个中午,和公司的一个哥们闲聊,我抛出了一个话题, "写代码这么多年,你觉得编程中最重要的是什么?"

然后我们开始balabala.... 不约而同说到了 "抽象",顿时有了一种惺惺相惜的快感。

当然,对于编程这么多年的我,自然有一些自己的理解:

  • 其一是编程思想
  • 其二是抽象

二者就像面包和鲜花

编程思想是无关编程技巧、编程语言,只要你想明白,就能通过各种手段去落地。

这也是为什么我没有学过 python,也能在短时间内用 python 写需求一样, 因为我用思想在指导我工作。

当我们解决温饱以后,就应该精神层面的东西了,那就是编程界的鲜花--抽象

这么多年来,也越发觉得抽象就是一门艺术,它让编程变得更加优雅。


二、python 结缘

因为业务上的变动,接盘了一些 python 开发的 AI 应用,当然先前没有使用过 python,但是实现需求要紧,那就开干吧!

于是我安装了 TONGYI Lingma 插件。(通义千问大模型插件,效果一般,基本够用,并且是免费)

TONGYI Lingma 的帮助下,我开始理解 python 代码, 并在其帮助下,磕磕绊绊地完成了第一个需求。

不过这些代码和刚毕业那会写的 Java 代码一样。大段粘贴复制重复代码,所有逻辑在一个方法中完成,没有抽象,全是面向过程编码。

当然第一个需求写这种代码是可以理解,但当第二个第三个这么开始的时候,场景只是稍微变了一丢丢,流程相似,于是照着先前写的逻辑,从头到尾复制一遍代码,改改部分逻辑, 突然觉得索然无味了。

虽然我对 python 不熟悉,先实现需求要紧,但是我还是忍不住想用面向对象的思想,去实现这些功能。

印象里 python 与脚本语言,算法、爬虫,数据挖掘等等有关,但唯独没有听过 python 与面向对象有联系。

直到接触 python 一个月后的今天,我用 python 写出一段面向对象的代码。

忍不住给旁边的哥们说 我用 python 写出面向对象的代码了,看起来确实优雅呀

那么今天我就用这个简单的需求,来证明一个道理:

面向对象编程和语言无关,它应该成为编程的利器!


三、 需求背景

AI题目:使用大模型给用户的问题回答打分。

当拿到这个命题的时候,内心窃喜,感觉比较 easy,把用户的问题和参考答案,交给大模型去打分就可以了。

指导思想分分钟解决。 如下图逻辑

  1. 用户输入答案
  2. 根据问题题目从题库中搜索参考答案
  3. 将参考答案和用户答案一起提交给大模型
  4. 大模型分根据 prompt 分析后输出结果

但是:考题会变,大模型的 prompt 可能会变,不能再继续写if..else ,不能再将所有代码写到一起了。

今天我准备干一件事情,

用面向对象编程的思维,以及不熟悉的 python 语言,去实现可复用、可扩展的功能模块。


四、编码实现

编程中最重要的是思想,其次是抽象。 面向对象,它的三个基本特征:封装、继承、多态

4.1 面向对象分析

根据需要,大致可以得到以下几个类。

1.问题和用户回答:UserAnswer,结构{"question":"xxxx","answer":"xxx"}。 使用对象后,子类可以在此基础上继承扩展

2.问题和参考答案:Question, 结构 { "question":"问题", "reference":"参考答案", "keyPoint":"答案中的关键点"}

3.问题库:QuestionManager,是对 Question 实体的管理 , 提供对问题 Question, init()、add()、get() 等方法

4.大模型:定义基类:BaseModel, 子类使用不同的大模型,比如通义千问、chatgpt等。提供 invoke(prompt) 方法,实现模型调用。 (为了大模型职责单一,暂且提供 一个方法, prompt是 template_prompt 和 参数拼接后的值)。

5.测评基类:BaseEvaluation(BaseModel llm, String promptTemplate),并提供 generate_prompt 为抽象方法,目的是构建最终的 可执行的 prompt。 核心逻辑使用大模型来处理。 evaluate(Question question, UserAnswer answer ) 方法提炼了评估的整个流程,子类可以扩展流程的步骤。

通过上面的分析,并给出类图

4.2 面向对象编码

接下来就是编码的时候了,我想使用 Java 我会很快地写出来,现在我将用 python 来完成。编程最重要的是思想,语言都是次要的。尤其是 AI 时代的今天。

例如:我将上面面向对象的分析过程,提交给 Kimi(月之暗面大模型)生成的代码

很快就能把代码生成了。非常高效,稍微改一下细节,即可上菜!

4.3 python 代码

根据上面的分析和类图,进行编码,给出部分代码。(可以使用上面的提示语,在大模型中快速生成!

实体类型 Question, UserAnswer

python 复制代码
class Question:
  def __init__(self, question, reference, key_point):
      self.question = question
      self.reference = reference
      self.key_point = key_point
  def __repr__(self):
      return f"Question(question={self.question}, reference={self.reference}, key_point={self.key_point})"

class UserAnswer:
  def __init__(self, question, answer):
      self.question = question
      self.answer = answer
  def __repr__(self):
      return f"UserAnswer(question={self.question}, answer={self.answer})"

QuestionManager

python 复制代码
class QuestionManager:
​
    def __init__(self):
        self.question_bank = []
​
    # 添加问题
    def add_question(self, question):
        if not self.get_question(question.question):
            self.question_bank.append(question)
​
    # 获取问题。 使用简单的题库
    def get_question(self, question_text):
        for q in self.question_bank:
            if q.question == question_text:
                return q
        return None

大模型基类 BaseModel

python 复制代码
from abc import ABC, abstractmethod
# 抽象一个模型
class BaseModel(ABC):
    @abstractmethod
    def invoke(self, prompt):
        pass

评估的基类 BaseEvaluation

python 复制代码
class BaseEvaluation(ABC):
    # 将 BaseModel 设置属性
    def __init__(self, model: BaseModel, prompt_template: str):
        self.model = model
        self.prompt_template = prompt_template

    # 实现评估处理,定义好结构
    def evaluate(self, question: Question, answer: UserAnswer):
        # 使用大模型进行评估,这里假设self.model是一个已经初始化的模型实例
        prompt = self.generate_prompt(question, answer)
        return self.model.invoke(prompt)
    @abstractmethod
    def generate_prompt(self, question: Question, answer: UserAnswer):
        pass

核心方法: evaluate,提供处理逻辑。 prompt 和 model 都是可以在子类中可更换。 (tips:有用到模版模式)

关键步骤:

  1. 构建 prompt
  2. 使用大模型处理

测试运行

输出测评结果。 面向对象编程的案例结束了。

4.4 一个 bad case

QuestionManager 的 add Question方法 通过传递三个参数和对象的比较


五、面向对象编程

面向对象的特性:封装、继承、多态。 它具有语言无关性。 python 小白的我,举了一个例子进行了佐证。

语言不应该成为我们的局限,AI/大模型 能够更好的辅助我们开发, 不管是编程语言、AI/大模型都只是工具,而编程思想才是灵魂。当然面向对象算是编程思维中的一部分。多修炼这些内功心法,以不变应万变。从平常的工作中思考、提炼总结、形成方法论,内化成能力。


六、结束语

以前我认为什么功能都需要使用 Java 语言去实现,并且还挺排斥非 Java 语言的功能实现,甚至瞧不上 python、go。 随着 chatgpt 等各种大模型火了之后,生成代码非常方便, 似乎 10 年的 Java 开发和 1 年的 Java 开发也没有那么大的差距了,"遇事不决问大模型"。因此我们应该更加开放地拥抱各种语言,要有能快速学习一门语言或者多门编程语言的心态。心态放开,让所有工具、语言为我所用,这样才能提高生产力。

感谢阅读,本章完!

相关推荐
一只叫煤球的猫6 小时前
写代码很6,面试秒变菜鸟?不卖课,面试官视角走心探讨
前端·后端·面试
bobz9657 小时前
tcp/ip 中的多路复用
后端
bobz9657 小时前
tls ingress 简单记录
后端
皮皮林5518 小时前
IDEA 源码阅读利器,你居然还不会?
java·intellij idea
你的人类朋友8 小时前
什么是OpenSSL
后端·安全·程序员
bobz9658 小时前
mcp 直接操作浏览器
后端
前端小张同学11 小时前
服务器部署 gitlab 占用空间太大怎么办,优化思路。
后端
databook11 小时前
Manim实现闪光轨迹特效
后端·python·动效
武子康12 小时前
大数据-98 Spark 从 DStream 到 Structured Streaming:Spark 实时计算的演进
大数据·后端·spark
该用户已不存在12 小时前
6个值得收藏的.NET ORM 框架
前端·后端·.net