java - 编写界面以涵盖终端和 2D UI 的最佳方式

标签 java

Java8:我想创建一个接口(interface)如下:

public interface Ui {
    abstract static void homeScreen();
    abstract static void exitSplash();
}

但是我得到错误:

error: illegal combination of modifiers: abstract and static
    abstract static void homeScreen();

对于static void abstract:

error: <identifier> expected
        static void abstract homeScreen();

我希望能够创建一个具有上述方法的类,我可以在其中编写自己的方法体,但它们是static,因为我不需要在其中创建对象为了显示主屏幕或退出启动画面(当然我没有 - 或者我无知地试图强制使用非 OOP 方法?)。
我不想向接口(interface)方法添加参数,因为想象两个实现 -

  1. 基于文本的用户界面,以及
  2. 二维用户界面。

他们有什么共同点?一个将全是 Swing 或等效物,另一个将与 Swing 无关。

这里有两个问题:

  1. 我认为这真的归结为我不了解基础知识。毫无疑问,有人会指责我“没有掌握 OOP 编程的基础知识”。但是我读过——相当多的书——但是当我尝试将事情付诸实践时,它只需要——练习! 关于接口(interface)方法描述的 abstractstatic 等的允许/不允许组合,有人可以为我指出正确的方向吗?

  2. 如何为不带参数的静态类方法创建接口(interface)方法。不可能吧!?那么我该如何解决我想要一个 UI 界面的小问题,它可以最好地涵盖终端和 2D UI?放弃并实例化类>我为什么要这样做?

注意:这是我想构建一个接口(interface)来覆盖的(测试)类。我喜欢它现在的样子,使用静态方法:

import java.io.IOException;
import jline.console.ConsoleReader;

class TestGameScreen2 implements Ui {
    private static ConsoleReader con;
    public static void homeScreen() {
        try {
            con.setPrompt("AwesomePrompt> ");

            Screen.clear();
            System.out.println("Press any key to continue...");
            con.readCharacter();
            Screen.clear();

            System.out.println("Here is a prompt. Do something and press enter to continue...");
            String line = con.readLine();
            Screen.clear();

            System.out.println("You typed: ");
            System.out.println(line);
            System.out.println("Press any key to exit. ");
            con.readCharacter();
            Screen.clear();
        } catch (IOException e) {
            e.printStackTrace();

    }
    }
    public static void exitSplash() {
        System.out.println("Thank You. Goodbye.");
        System.out.println("");
    }
    public static void main (String argv[]) {
        try {
            con = new ConsoleReader();
            homeScreen();
            exitSplash();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

最佳答案

不能将一个方法同时定义为static abstract 的原因:

abstract methods require implementation (via inheritance). static members belong to the class, removing intentions of inheriting. You cannot override a static method, only hide it.

您绝对是在强制使用“非 OOP”方法。没有理由为此需要 static

短期对象在面向对象代码中很常见。堆的结构专门用于处理具有不同生命周期的对象。启动画面/欢迎画面就是一个很好的例子,只存在很短的一段时间。


至于您的设计,我看到您担心应用正确的 OOP 设计原则。以下是我能够指出的一些缺陷:

Single Responsibility :将启动和结束启动代码放入 UI 类型中,使 UI 负责启动。您应该通过允许 SplashScreen 类型来处理此类问题来降低责任。然后您可以让 UI 请求 SplashScreen:

abstract class UI {
    private SplashScreen splash;

    public UI(SplashScreen splash) {
        this.splash = splash;
    }

    public void start() {
        splash.start();
        init();
        splash.end();
    }

    public abstract void init();
}

init 用作模板方法,允许实现在启动过程中自行初始化。通过将启动画面的代码移到另一个对象中,我们降低了 UI 的责任。除此之外,您可以通过传入不同的 SplashScreen 实现(遵守 open/close principle)轻松切换启动画面,而无需修改类。

Interface Segregation :并非所有 UI 都有启动画面。这意味着某些实现可能不会使用 startSplashexitSplash。相反,您应该隔离接口(interface)。创建不同的抽象:一种支持飞溅,一种不支持:

abstract class UI {
    public abstract void start();
}

abstract class SplashableUI {
    private SplashScreen splash;

    public SpashableUI(SplashScreen splash) {
        this.splash = splash;
    }

    public final void start() {
        splash.start();
        init();
        splash.end();
    }

    public abstract void init();
}

接口(interface)很好,但是只能抽象行为,不能抽象状态。设计时要考虑可扩展性。您可能希望向您的 UI 类型添加一些共享状态。这将迫使您重构它的所有实现,以便将其转换为抽象类。

就个人而言,我使用接口(interface)通过行为来弥合不同类型层次结构之间的差距。例如:

              Entity
            /           \
Humanoid    Animal
         |               /     \
   Human    Bird    Fish

HumanFish 分为 2 个不同的类型层次结构。但他们都可以 swim()。如果我们想要一个接受任何可以游泳的东西的 SwimmingPool 类,我们有 3 个选项:

  1. SwimmingPool 类中声明所有可以游泳的类型(accept(Person)accept(Fish) 等...) .但这不可扩展
  2. 创建一个 SwimmableEntity 类型。但是我们需要 NonSwimmableEntity。最重要的是,我们需要 SwimmableAnimalNonSwimmableAnimal...您将拥有一堆非常相似的接口(interface),创建比需要更多的类型层次结构。
  3. FishHuman 实现一个 Swimmable 接口(interface),然后允许 SwimmingPool 接受该类型的对象。

关于java - 编写界面以涵盖终端和 2D UI 的最佳方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33723522/

相关文章:

java - hibernate 对象加载失败

java外部函数调用saxon 9.9he xslt

java - 检查对象是否存在被 webdrivereventlistener 捕获时,Selenium webdriver 出错?

java,mysql - 为什么不能从一个表中获取最后插入的 id 并将其再次插入到另一个表中?

java - 需要帮助测试我的类(class)

java - 将文件从 Jenkins 工作区(从 Docker 容器内部)复制到本地驱动器

java - 在人民之间平分价格的公式

java - ConcurrentHashMap 上的元素循环

java - 在 Webapp 项目中使用 Tomcat 库

java - 如何使用更具体的对象家族(A' < : A has many B' <: B)?)扩展对象家族(A 有很多 B)