简体   繁体   English

创建接口参考并将其分配给实现对象认为是一个干净的设计决策

[英]Creating reference of Interface and assigning it the implementing object considered a clean design decision

I have a base class called Tiger 我有一个叫老虎的基础班

class Tiger implements Attack{
@Override
public void pounce(int intensity){
}
@Override
public void threatLevel(int level){
}

} }

Attack interface: 攻击界面:

Interface Attack{
void pounce(int intensity);
void threatLevel(int level);
 }

Another subclass SiberianTiger 另一个子类SiberianTiger

class SiberianTiger extends Tiger{
public void setupSiberianTiger(int intensity,int level){
  pounce(intenisty);
  threatlevel(level);
}

} }

public static void main(){
Attack attack =new SiberianTiger();
//setup the Siberian Tiger meow >.<
((SiberianTiger)attack).setupSiberianTiger(4,5);
}

So my question is it a good design decision to initialize the SiberianTiger instance the way I am doing. 所以我的问题是,按照我的方式初始化SiberianTiger实例是一个好的设计决策。 How can I improve upon it. 我该如何改进。
((SiberianTiger)attack).setupSiberianTiger(4,5); (((SiberianTiger)攻击).setupSiberianTiger(4,5);

You should declare your variables with the type you know you will use the fields and methods available. 您应该使用您知道将使用可用字段和方法的类型来声明变量。 In this case, there's no benefit in declaring this: 在这种情况下,声明以下内容没有任何好处:

Attack attack = new SiberianTiger();
((SiberianTiger)attack).setupSiberianTiger(4,5);

It is better to declare the variable as SiberianTiger : 最好将变量声明为SiberianTiger

SiberianTiger siberianTiger = new SiberianTiger();
siberianTiger.setupSiberianTiger(4,5);

The benefit of using super class or interface cannot be seen in this small piece of code. 在这小段代码中看不到使用超类或接口的好处。 For instance, you can see it if you have a collection of Attack s: 例如,如果您有Attack的集合,则可以看到它:

List<Attack> attackList = new ArrayList<>();

SiberianTiger siberianTiger = new SiberianTiger();
siberianTiger.setupSiberianTiger(4,5);
attackList.add(siberianTiger);

for (Attack attack : attackList) {
    attack.<doSomething>();
}

Of course, there are other ways to improve this design like creating a proper constructor for SiberianTiger where you pass the variables, apply Factory Pattern or Builder, etc. 当然,还有其他方法可以改善此设计,例如为SiberianTiger创建适当的构造函数,在其中传递变量,应用Factory Pattern或Builder等。

I would write a factory class and avoid the casting. 我会编写工厂类,并避免强制转换。

Clients should deal with Attack references, not concrete subtypes. 客户应处理Attack参考,而不是具体的子类型。

I agree with the comment about the interface name: good names matter. 我同意有关接口名称的评论:好名字很重要。 I'd prefer Attacker . 我更喜欢Attacker

public class AttackerFactory {
    private static final AttackerFactory instance = new AttackerFactory();

    private AttackerFactory() {}

    public static AttackerFactory getInstance() { return instance; }

    public Attack createAttacker(Class<Attack> attackerClass, int intensity, int threatLevel) {
        // Create what you want here
    }
}

No. A design that requires you to cast is not clean. 否。需要铸造的设计不干净。 Fortunately for you, there's an easy alternative in this case: 幸运的是,在这种情况下,有一个简单的选择:

public static void main(){
    SiberianTiger attack = new SiberianTiger();
    //setup the Siberian Tiger meow >.<
    attack.setupSiberianTiger(4,5);
}

More generally, you should always declare the least-specific type that is consistent with your usage requirements . 更一般而言,您应始终声明与使用要求一致的最少特定类型。 In your case, you want to use an initialization method that is specific to class SiberianTiger , so that's the type you should be declaring. 在您的情况下,您想使用特定于类SiberianTiger的初始化方法,所以这就是您应该声明的类型。

You can certainly pass that SiberianTiger object to a method that accepts any kind of Attack , or assign it to such a variable, etc.. That's an altogether different matter. 您当然可以将SiberianTiger对象传递给可以接受任何一种Attack ,或者将其分配给这样的变量,等等。这是完全不同的事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM