Java - 是不是接口太多了?

Java - Is there such a thing as too many interfaces?

我已经编程几年了。界面似乎一直是我难以琢磨的话题。将尽可能多的功能抽象到接口中是一种好的做法吗?

我从来没有完全理解它们的好处。我一直认为"why not just write the methods normally"。它们只是方法。然后我开始学习依赖注入以及它如何真正简化代码,让构造函数成为 class.

与外界的主要联系点

但是,最近,我又开始考虑接口,以及如何像类型一样随意使用它们,而不仅仅是一种标记方法的可爱方式。

所以在我的第一个真正的接口使用实验中 Java,我做了这个例子,我想知道的是:

对于了解接口强大功能的 Java 开发人员,我编写的这一小段代码是否说明了一个好的模式或一个好的思路?到目前为止,这段代码基本上是好的吗?我只想知道我是否走在正确的道路上。我明天要参加第二次面试,我想在面试中提出这个认识,当且仅当我走在正确的道路上。

代码如下:

interface Fightable{
void kick(Fightable enemy);
void punch(Fightable enemy);
void takeDamage(Fightable enemy, String typeOfStrike);
void strikeEnemy(Fightable enemy, String typeOfStrike);
}

interface CanEat{
void chew();
void swallow();
}

interface MotherShip{
int motherShipBoost = 50;
String getColony();
void sendHelp(int[] location);
String buildMoreShips(int amount);
void flyToNewSystem(String newSystem);
int[] beamDownRandomly();
}

interface Animatable{
void animateChew(CanEat eater);
void animateSwallow(CanEat eater);
void animateMove(Moveable mover);
void animateRevive(CanEat eater);
void animateStrike(Fightable striker, Fightable receiver, String typeOfStrike);
}

interface Moveable{
void setNewLocation(int []newLocation);
int[] getLocation();
void move();
}

public class GameCharacter implements Fightable, CanEat, Moveable{

private int health;
private String name;
private int[] location;
private String stamina;
private String origin;
private String colony;
private Animatable animator;
private MotherShip motherShip;
private boolean isRecruited;

public GameCharacter(MotherShip motherShip, String name, Animatable animator){
    this.motherShip = motherShip;
    this.animator = animator;
    this.name = name;
    this.location=this.motherShip.beamDownRandomly();
    this.colony = this.motherShip.getColony();
}


@Override
public void kick(Fightable enemy) {
    strikeEnemy(enemy, "KICK");

}



@Override
public void punch(Fightable enemy) {
    strikeEnemy(enemy, "PUNCH");
}

@Override
public void takeDamage(Fightable enemy, String typeOfHit) {
    this.health = this.health - 3;
    animator.animateStrike(enemy, this, typeOfHit);
    if(this.health < 10){
        motherShip.sendHelp(this.location);
    }
}

@Override
public void strikeEnemy(Fightable enemy, String typeOfStrike) {
    enemy.takeDamage(this, typeOfStrike);
    animator.animateStrike(this, enemy, typeOfStrike);
}

@Override
public void chew() {
    animator.animateChew(this);

}

@Override
public void swallow() {
    animator.animateSwallow(this);
    health = health + 10;
    animator.animateRevive(this);
}

@Override
public void setNewLocation(int[] newLocation) {
    this.location = newLocation;
}

@Override
public int[] getLocation() {
    return this.location;
}

@Override
public void move() {
    animator.animateMove(this);
}
}

我的想法对吗?

感谢您的任何反馈

-T

首先,存在接口以实现其中描述的所有非默认方法。可以很容易地用抽象 class 代替。但是,为了以更简单的方式进行清理,已经实现了接口。

一旦看起来合乎逻辑并且让您更容易使用界面,就没有太多界面这样的事情。但是,一旦您或您的同事为拍照而头疼,那就太多了。

使用界面作为简化清理和结构化过程的额外方式。

此外,java 不支持 class 的多重继承。因此,通过使用接口,您可以像示例中那样拥有多重继承。

干得真好,祝你面试顺利!

我会尽我所能以最好的方式回答你的问题。

1.

将尽可能多的功能抽象到接口中是一种好的做法吗? 让我们从基础开始 a) 记住接口只不过是 "contracts",一个实现接口的参与者基本上承诺遵守和交付合同条款和条件的承诺。 b) 接口在代码中充当出色的设计工具,本质上允许生产者和参与者专注于他们的高级交互,而不必担心实现细节。

在 CS 基础知识外行人的术语中,接口承诺一致性,本质上是 3 件事。 1. 一个 said functionality/operation/function/method 可用的承诺 2. 此功能接受所述同意的输入 3.(如果实施)此功能将产生上述结果。

因此,当一项服务(class/soap 消息等)提供实现接口的意图时,它公开同意 "contract" 的这 3 个条款,任何偏离它们的行为都是违反合同。

2.

是的,你是绝对正确的,接口在 SOLID design principles 中的 Ioc(控制反转)方面确实展示了它们的力量,它允许 IoC 容器解析(提供)并为合适的参与者提供服务(实现)通常在 运行 时间履行合同,因此系统开发人员无需担心实现细节。

但也许 Ioc 的好处往往只有在实施 service locator pattern 时才能实现,因此,"how does a developer or team benefit from using interfaces as a design tool?" 成为一个重要的问题。

单身开发者 举个例子,我正忙着编写一个新的软件系统,在白天,我全神贯注于我想为用户提供的功能类型,也许能够在一般意义上管理他们的待办事项列表,这需要"create" 新待办事项、"clear-check" 现有待办事项和 "remove" 待办事项 collection 的能力。现在有几种方法可以实现这些功能中的每一个,我变得懒惰了,我宁愿在下周只交付其中一个功能,但我可能会忘记我最初的想法并最终实现我自己的功能随着时间的推移,根据我的影响,为了约束自己并坚持我最初的想法,我选择宁愿提前起草这个功能的合同而不实际实施它,这将允许我模拟这些功能而不是实际实施它们。因此,通过使用接口,我已经为接下来几周需要实现的目标奠定了基础,我可以每隔一天回过头来完成我的功能,而不会违背我的诺言……这将我们带到下一个主题现在我不会深入研究 Open Close principles(SOLID 中的 O),它基本上表示我的设计对外部更改关闭但对内部更改开放,并且可能对扩展(添加)开放。所以我可以在不破坏现有合同的情况下向我的待办事项服务添加新功能,并且我可以更改它们的实现行为但不能更改现有功能的形状。

在一个团队中 我与 Lindile 和 Selebalo 一起实施虚拟卡系统,由于工作量太大,我们决定我将专注于核心银行系统(余额分类账),而 Lindile 将专注于 VC 的存款,而Selebalo 专注于 VC 的存款。在我们的初始设计 session 中,我们从核心银行业务开始进行由内而外的设计,并描述哪些操作可用于更新客户的帐户,经过几个小时的讨论,我们决定核心银行系统将提供两种功能,一个用于将钱添加到一个帐户中,称为 "credit" 接受金额和 "debit" 扣除或减少也接受金额的客户帐户。但是因为除了借方和贷方之外,核心还必须处理很多其他事情(客户信用档案、反洗钱等),所以可能需要一段时间才能说这些人可以集成和测试他们的代码,所以我们决定签订一份合同

的核心银行业务
public interface ICoreBankingServices{

Balance Debit(decimal amount,Currency c);
Balance Credit(decimal amount, Currency c);

}

现在 Lindile 和 Selebalo 可以假设我会遵守合同并选择模拟或模拟借方和贷方的结果,直到我们都准备好集成和测试,因此我的功能没有开发依赖性让他们工作,这是一件积极的事情。

我希望这些示例能够说明使用接口、设计工具和依赖关系解耦机制的一些基本好处。

我没有 Java 期望,但如果游戏角色必须战斗、进食和移动,那么你就走对了。您只需要以增加复杂性为代价来关注您所做的解耦级别(与规范化相同),但没有任何指导方针,只要事情不会变得太复杂,您就可以在逻辑上尽可能多的接口..当涉及到多重实现继承时,请不要应用相同的想法,但这是个人意见 :)

您最终将不得不缴税并更多地了解设计模式以及它们试图解决或简化的内容,以便加深您对设计更好系统的理解。