当前位置: 首页 > 面试题库 >

适用于简单聊天应用程序的设计模式

冯星剑
2023-03-14
问题内容

我正在设计一个简单的聊天应用程序(仅此而已)。我一直想知道该聊天应用程序的简单设计。为了给您概述..这是规则:

  1. 匿名用户仅使用昵称输入聊天。(用户ID)大概是由系统在后台分配的。
  2. 他们可以加入(订阅)聊天对话。并且他将看到来自其他用户的聊天文本出现在指定区域。
  3. 他们可以回复特定的对话,其他所有人都应该看到。

而已!(请参阅我告诉您的那是一个简单的聊天应用程序)。因此,我的意图并不是真正的应用程序。但是设计模式和其中使用的对象。

现在这是我的设计方式。(我在用java ..编码,以防万一真的很重要)

  1. 用户对象-两个属性ID和昵称
  2. 消息对象-一个简单的消息接口和实现(目前)为SimpleMessage,具有String作为包含消息的属性。
  3. 聊天窗口对象-基本上由用户和消息组成。由于它具有一个用户对象和消息列表。
  4. 聊天会话-再次组成。基本上它将有一个聊天窗口列表。每个聊天窗口都会注册一个聊天会话。聊天会话负责在出现新消息时通知所有聊天窗口。(观察者模式有人吗?)

好吧..现在我通过使ChatWindow实现具有称为“ notify(Message)”方法的“
ChatListener”模式来实现观察者模式。因此,ChatSession会通知每个已注册的ChatWindow。

现在,我想澄清/希望您提出一些意见。1.我还需要对所有聊天窗口都使用注销方法,以防聊天窗口关闭并且不想再收到任何通知。这可能意味着,要么我应该拥有一个仅具有一个实例的“静态”中央注册管理器,然后任何聊天窗口都应该能够通过提供“聊天会话”
ID来注销自身。因此,每个聊天会话都应具有一个ID。(包括在此处)。或者,我也可以在“聊天窗口”中维护一个ChatSession实例,以始终准备好一个实例。(我讨厌单身人士,因为我认为它们不利于哎呀)。另一种方法是不对聊天窗口取消注册控制,而使用聊天窗口,

  1. 这种设计有道理吗?如果您说这是CRAP的一部分,请给我一个更好的方法;您肯定会从我这里得到极大的感谢。除了观察者模式以外,这里可以使用所有模式来进一步简化它或使其变得更好。另外,此设计的任何弱点,如果适当,但可以改进。

  2. 同样,当用户在自己的聊天窗口中键入新消息时;它必须传播到所有聊天窗口,这是聊天会话要做的,但同时;这是否意味着..聊天会话需要获取带有“聊天窗口ID”和消息的消息?然后将其传播到所有窗口,包括消息所有者之一?有什么更好的方法来解决这个问题。我的意思是,一种让窗口让聊天会话知道消息,然后再与所有其他窗口聊天的方式。(我想如果需要的话就需要一些…也不喜欢它们)

无论如何…请让我知道您的评论。还请雷姆。工作应用不是目的,我正在寻找一个好的讨论,良好的设计模式实践和用法。

完整的代码,如果给您很高的评价,请…随时将其拆开,并提出与几乎所有语义相关的问题。

package com.oo.chat;

public class User {

    private Long userId;
    private String nickname;

    public User(Long userId, String nickname) {
        this.userId = userId;
        this.nickname = nickname;
    }

    public void setUserId(Long userId) {
        this.userId = userId;
    }

    public void setNickname(String nickname) {
        this.nickname = nickname;
    }

    public Long getUserId() {
        return userId;
    }

    public String getNickname() {
        return nickname;
    }

    public boolean equals(Object objectToCompare) {
        if (!(objectToCompare instanceof User)) {
            return false;
        }
        User incoming = (User) objectToCompare;
        if (incoming.getNickname() != null && incoming.getUserId() != null) {
            if (incoming.getNickname().equalsIgnoreCase(this.nickname)
                    && incoming.getUserId().equals(this.userId))
                return true;
        }
        return false;
    }
}


package com.oo.chat;

public interface Message {

    public String getValue();

    public void setValue(String value);

}

package com.oo.chat;

public class SimpleMessage implements Message {

    private String value;

    public SimpleMessage() {

    }

    public SimpleMessage(String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}

package com.oo.chat;

public interface ChatListener {

    public void notify(Message newMessage);

}

package com.oo.chat;

import java.util.ArrayList;
import java.util.List;

public class ChatWindow implements ChatListener {

    private User user;
    private List<Message> messageList;
    private Long id;

    public User getUser() {
        return user;
    }

    public List<Message> getMessageList() {
        return messageList;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public void setMessageList(List<Message> messageList) {
        this.messageList = messageList;
    }

    public void addMessageToList(Message newMessage) {
        if (this.messageList == null) {
            this.messageList = new ArrayList<Message>();
        }
        this.messageList.add(newMessage);
    }

    public void notify(Message newMessage) {
        addMessageToList(newMessage);
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }
}

package com.oo.chat;

import java.util.ArrayList;
import java.util.List;

public class ChatSession {

    private List<ChatListener> registeredChatListeners;

    public void register(ChatWindow chatWindow) {
        if (registeredChatListeners == null)
            registeredChatListeners = new ArrayList<ChatListener>();
        registeredChatListeners.add(chatWindow);
    }

    public List<ChatListener> getRegisteredChatListeners() {
        return registeredChatListeners;
    }

    public void setRegisteredChatWindows(
            List<ChatListener> registeredChatListeners) {
        this.registeredChatListeners = registeredChatListeners;
    }

    public void incomingMessage(Long chatListenerId, Message message) {
        publish(message);
    }

    protected void publish(Message messageToPublish) {
        if (registeredChatListeners != null) {
            for (ChatListener eachListener : registeredChatListeners) {
                eachListener.notify(messageToPublish);
            }
        }
    }
}

在此先感谢所有贡献者。干杯


问题答案:

只看User对象,为什么平等取决于id
nickname?在我看来,这有点反常。我希望您有一个id,那么那就是对象的标识,因此可以在相等条件下使用。

我还看到您有一个用于用户ID的设置器。那么,您真的要更改用户ID吗?我发现您可以更改昵称,这很有意义。但我希望ID保持不变。

还要注意,由于要覆盖equals(),因此还应该覆盖hashCode()。

现在,如果hashCode()和equals()依赖于不可变字段(例如id),则hashCode()的结果将不会改变,如果将User放入哈希集合(例如HashMap)中,则以后再也不会丢失它(这很令人困惑)!

最后(!),我将保护构造函数和设置器免受空昵称(使它们抛出IllegalArgumentExceptions),然后使equals()之类的代码不必担心空昵称(除非’null’代表昵称)。我对id也会这样做,因为您将其作为Long(对象)。但这不是一个原始的时间吗?



 类似资料:
  • 我正在使用聊天应用程序,我需要每一秒钟刷新一次列表。我使用处理程序重复调用该方法,但是它没有更新< code>ListView。我正在调用该方法中更改的通知数据集。 Messages.java 聊天适配器.java 更新的Message.java ChatDetail.xml ChatLeft.xml chattright . XML

  • 本文向大家介绍Android编写简单的聊天室应用,包括了Android编写简单的聊天室应用的使用技巧和注意事项,需要的朋友参考一下 最近写了一个简单的聊天室应用,可以发送表情,更改头像这些功能。主要技术点就是怎样把表情图片放到textview等Ui控件中展示。这里废话不多说,下面是效果图:  这里主要讲下怎样把文本替换到表情,先说下思路,首先我们的图片是保存在本地资源目录drawable中而所有的

  • 问题内容: 我想知道为数千名用户编写聊天应用程序的正确方法是什么。 我只是感到困惑,我如何才能每秒使用AJAX或更少的方法来对服务器执行ping操作,并检查MySQL中是否有新记录等,并且服务器负载可以接受。 我目前正在考虑使用jQuery,PHP和MySQL进行编码。 请指教。您的帮助将不胜感激。 问题答案: 客户端 对于需要轮询服务器的任何程序,我建议使用WebSockets。 我写了一个非常

  • 我正在使用XMPP在app引擎上编写一个聊天应用程序。我的想法是允许用户互相聊天。我可以将消息发送到google talk帐户,方法是将登录的用户删除地址的@gmail.com部分,并将其替换为@appid.appspotchat.com)。例如,如果登录的用户是bob@gmail.com,则用于发送的jid将是bob@appid.appspotchat.com)。然后,您可以将消息发送到goog

  • 现在我们已经熟悉了Socket.IO,让我们编写一个聊天应用程序,我们可以用它在不同的聊天室聊天。 我们将允许用户选择用户名并允许他们使用它们进行聊天。 首先,让我们设置我们的HTML文件来请求用户名 - <!DOCTYPE html> <html> <head> <title>Hello world</title> </head> <script src = "/s

  • 我希望基本上在我的应用程序内翻拍Kik。对于我在firebase聊天应用程序上看到的大多数指南,都有一个主要的消息节点,然后在该节点下面有一个扇出,每个用户都有引用主列表中消息的消息。 根据目前我的Firebase的布局方式,实现类似以下内容会更容易: 因此,当用户向对方发送消息时,我会更新发送者和用户下面的“聊天消息”节点。 有什么理由不这样做吗?我看到每个人都按照我描述的第一种方式进行,但我看