首页 > 编程语言 >关于java装饰器模式在ai生成举例不可用的问题

关于java装饰器模式在ai生成举例不可用的问题

时间:2024-07-15 12:27:29浏览次数:16  
标签:java messageComponent MessageComponent ai 装饰 举例 Message public

定义

首先描述下定义,然后举例说明。

网上定义

装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许向对象添加新的功能或职责,同时保持对象类的原始结构。这种模式提供了一种替代继承的机制来扩展功能,因为继承通常是在编译时固定的,而装饰器模式则允许在运行时动态地添加行为。

理解

这边分一下结构,组成主要分为
1,组件接口:Component,定义基本行为
2,具体组件:Concrete Component,实现组件接口,是装饰器可以添加行为的基本对象
3,装饰器:也实现Component接口,并且有对该接口的引用,通常指向另一个具体装饰器或者具体组件。装饰器可以在被调用时将请求转发给引用的对象,也可以在转发后添加自己的行为。
4,具体装饰器,具体装饰器继承装饰器,会在不改变组件接口的前提下,加入新的功能。(核心)

ai举例

这里用的是通义千问(阿里的gpt2.5)
发出请求:

java的装饰器模式写个demo

ai回复的

下面我将使用装饰器模式来创建一个简单的文本输出系统,其中基础的Message类用于生成基本的消息,而装饰器则用于添加额外的行为,比如在消息前后加上标签或者转换消息大小写。
首先,我们定义一个抽象的接口MessageComponent,所有的消息组件都将实现这个接口:

public interface MessageComponent {
    void print();
}

接下来,我们创建一个基础的Message类,它实现了MessageComponent接口:

public class Message implements MessageComponent {
    private String text;

    public Message(String text) {
        this.text = text;
    }

    @Override
    public void print() {
        System.out.println(text);
    }
}

现在我们创建一个装饰器基类MessageDecorator,它同样实现MessageComponent接口,并且持有MessageComponent类型的实例,这样就可以对传入的对象进行装饰:

public abstract class MessageDecorator implements MessageComponent {
    protected MessageComponent messageComponent;

    public MessageDecorator(MessageComponent messageComponent) {
        this.messageComponent = messageComponent;
    }

    @Override
    public void print() {
        messageComponent.print();
    }
}

然后,我们可以创建具体的装饰器类,例如TaggedMessage和UpperCaseMessage:

public class TaggedMessage extends MessageDecorator {
    private String tag;

    public TaggedMessage(MessageComponent messageComponent, String tag) {
        super(messageComponent);
        this.tag = tag;
    }

    @Override
    public void print() {
        System.out.print("<" + tag + ">");
        super.print();
        System.out.println("</" + tag + ">");
    }
}

public class UpperCaseMessage extends MessageDecorator {
    public UpperCaseMessage(MessageComponent messageComponent) {
        super(messageComponent);
    }

    @Override
    public void print() {
        String upperText = ((Message)messageComponent).text.toUpperCase();
        System.out.println(upperText);
    }
}

最后,我们在主函数中使用这些类:

public class Main {
    public static void main(String[] args) {
        Message originalMessage = new Message("Hello, world!");
        Message taggedMessage = new TaggedMessage(originalMessage, "h1");
        Message upperCaseMessage = new UpperCaseMessage(taggedMessage);

        upperCaseMessage.print();
    }
}

运行这段代码,你会看到输出如下:

< h1 >HELLO, WORLD!</ h1 >

这就是一个使用装饰器模式的简单示例。装饰器模式的优点在于它可以灵活地增加功能而不改变现有代码,使得系统更加模块化和可扩展。

解析

可以看到提供了一个比较详细的例子,我们按结果顺一遍:
组件接口------>MessageComponent,ai定义了一个打印方法
具体组件------>Message类,实现上面的组件接口,并加入新的内容text,重写打印方法,使其打印出text的值。
装饰器------>抽象类MessageDecorator,也实现了上面的组件接口,加入新属性,重写的打印方法调用print()方法进行输出。
具体装饰器------>
TaggedMessage,ai为信息做了个分类,继承了装饰器,写了一个构造方法,用来创建对象,重写的print,做了自定义输出。
UpperCaseMessage,同上
最后写了一个测试方法

Message taggedMessage = new TaggedMessage(originalMessage, "h1");

上面就是基本创建对象,下面就开始爆红了

Message taggedMessage = new TaggedMessage(originalMessage, "h1");
Message upperCaseMessage = new UpperCaseMessage(taggedMessage);

错误为:incompatible type(数据类型不相容)
我将这个反馈给ai,然后ai就开始经典的所答非所问了,很多模型都有这个问题,有时候很聪明,你不问的他也帮完善,有时候就跟现在一样,陷入自己的思维误区里,继续追问只会让代码变复杂,几乎没可能得到解决办法。
但是代码归代码,我们还是可以参考一部分解释文本:
在UpperCaseMessage装饰器中直接将messageComponent转换成Message类型来获取text字段,这是不正确的,因为messageComponent可能是一个装饰器而不是原始的Message对象,它并不保证有text字段。
那根据ai的意思,类型转换错误,其实吧所有message换成messageComponent就行了,像这样

MessageComponent taggedMessage = new TaggedMessage(originalMessage, "h1");
MessageComponent taggedMessage = new TaggedMessage(originalMessage, "h1");
MessageComponent upperCaseMessage = new UpperCaseMessage(taggedMessage);

原因

在java里,你不能吧一个接口的实现直接赋值给另一个实现该类的变量,除非那个类本身也是该类的子类或者就是其本身,改动是因为MessageComponent类型是所有类(Message和所有装饰器)共有的超类型,这样,就可以将任何实现MessageComponent接口的类的对象赋值给这些变量。

关于ai

以上使我们自主修改的,但实际上我们既然已经依赖ai来给我们生成答案了,也应该尝试让ai这次会话走出这个误区,来实现我们的功能,不然总会出现代码多半只能用作参考,需要人为修改的情况。

首先,直接说解决问题的办法

新建一次会话,将你的全部代码发给ai,然后运行代码,将编译器报错的原因赋值给ai,这样它就会给你较为精准的回复,同时没有上一次会话的固定思维,这次会简介快速很多。

原因

有一些错误的问法会导致ai的行为和你预计的出现偏差,比如上面的报错,我如果直接询问:

   Message taggedMessage = new TaggedMessage(originalMessage, "h1");
    Message upperCaseMessage = new UpperCaseMessage(taggedMessage);
这两句代码发生报错incompatible type(数据类型不相容)

ai给出的回答格式就是:
在Java中,当你遇到“incompatible types”错误时,这通常意味着你正试图将一种类型的对象赋值给另一种不兼容的类型变量。在这个上下文中…
你的想表达的想法是:我提出来了有错的地方,你根据上下文帮我修改代码。
ai理解的是,你提出来了一个问题,再根据这个分析你的代码,帮你去完善代码。
这就出现了意见分歧,他会给你补充更多的代码,导致并未解决问题,反而代码越来越长,越来越乱。
这个时候,其实ai就已经陷入思维误区了,当本次对话你让他再去修改的时候,只要并未明说编译器的报错报文,它就会一直帮你完善下去,直到你放弃使用本次会话去完善。)
大概就是这个样子,对很多版本的ai代码完善功能也同样适用,当新建且直接提供编译器报错报文,比如这个:
在这里插入图片描述
的时候,ai的修复成功率最高。

标签:java,messageComponent,MessageComponent,ai,装饰,举例,Message,public
From: https://blog.csdn.net/qq_55332182/article/details/140429919

相关文章

  • Spring AI(聊天程序)
    接上篇:SpringAI(基础开发准备) 1、聊天程序(调用一次接口)packagecom.ithailin.controller;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importorg.springframework.ai.openai.OpenAiChatModel;importorg.springframework.beans.factory.annotation.Auto......
  • Java中的静态与动态绑定
    Java中的静态与动态绑定大家好,我是微赚淘客系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!静态与动态绑定的基本概念在面向对象编程中,静态绑定(StaticBinding)和动态绑定(DynamicBinding)是Java中重要的概念。本文将深入探讨这两种绑定方式的特点、使用场景以及在实际开发中......
  • AI学习 | chatgpt_api 和 tiktoken使用
    fromopenaiimportOpenAIimporttiktoken 如何使用chatgpttoken#创建实例,因为密钥已经传入环境变量,所以这里不用输入了client=OpenAI()#开始对话 response=client.chat.completions.create(model="gpt-3.5-turbo",messages=[{"role":"sys......
  • Java毕业设计-基于springboot开发的医院后台管理系统设计与实现-毕业论文(附毕设源代码
    https://download.csdn.net/download/u014740628/88922529医院后台管理系统设计与实现应用技术概述在信息时代背景下,医院后台管理系统的开发成为提升医疗信息处理效率的关键。本文介绍的系统采用B/S架构,结合了MySQL数据库和Java语言进行实现,确保了系统的稳定性和数据的安......
  • Java中的装箱与拆箱详解
    Java中的装箱与拆箱详解大家好,我是微赚淘客系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!装箱与拆箱的基本概念在Java中,装箱(Boxing)和拆箱(Unboxing)是指将基本数据类型与它们对应的包装类之间进行相互转换的过程。Java为每种基本数据类型提供了对应的包装类,如Integer对应in......
  • Java毕业设计-基于springboot开发的医院药品管理系统设计与实现-毕业论文(附毕设源代码
    Java毕业设计-基于springboot开发的医院药品管理系统设计与实现-毕业论文(附毕设源代码)https://download.csdn.net/download/u014740628/88922533医院药品管理系统开发实践应用技术概述在数字化时代背景下,医院药品管理系统的开发利用了当前流行的技术栈,以满足现代医疗行业......
  • AI学习 | 概念解释 + Scikit-learn 的简单情况
    一些机器学习概念解释点击查看代码*机器学习:是AI的一个子集,不用人类显式编程,让计算机通过算法自行学习和改进*监督学习:有数据、有标签,告诉机器什么是什么,让机器来学习输入和输出的映射关系。比如:分类和回归(预测)*非监督学习:有数据没有标签,让机器自己寻找规律。比如:聚类......
  • 使用Java实现OAuth2.0认证
    使用Java实现OAuth2.0认证大家好,我是微赚淘客系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!OAuth2.0认证简介OAuth2.0是一种开放标准的授权协议,允许用户授权第三方应用访问其资源,而无需将用户名和密码提供给第三方应用。在Web开发中,OAuth2.0已经成为一种常见的认证机制,用......
  • JavaScript中的new map()和new set()使用详细(new map()和new set()的区别)
    Map对象是一种键值对的集合,其中的键是唯一的,值可以重复。newSet():在JavaScript中,newSet()是用来创建一个新的Set对象的语法。Set对象是一种集合,其中的值是唯一的,没有重复的值。newSet()可以用来创建一个空的Set对象,在创建时传入一个数组或类数组对象,Set会自动去......
  • Java中的反射与注解结合使用
    Java中的反射与注解结合使用大家好,我是微赚淘客系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!反射与注解的基础概念在Java编程中,反射(Reflection)和注解(Annotation)是两个强大的特性,它们可以让我们在运行时获取类的信息并动态操作类的成员,同时可以通过元数据为代码添加标记......