战士,巫师和游戏规则

时间:2018-03-02 15:29:23

标签: java oop inheritance

我不久前在problem工作,责任主题和应该去的地方出现了。在我的链接问题中,大学是持有所有规则的机构和班级,并确保每个学生注册,都有所需的文件。

这让我想起Eric Lippert写的一篇博文:Wizards and Warriors

它的内容如下:

  

我们继续谈论“规则”,显然是业务   该程序的域包括称为“规则”的东西,以及那些   规则与业务域中的所有其他对象进行交互。所以   那么应该“统治”成为一个阶级?我不明白为什么不!它是什么的   程序基本上是关于。似乎可能存在   数百或数千条这些规则,并且它们可以改变   时间,因此将它们编码为类似乎是合理的。

规则:

  • 战士只能使用剑。

  • 向导只能使用员工。

我的问题是如何在GameRules class中确定传递的具体对象以验证我是否可以携带它?

public final class GameRules {

    public static boolean verifyifwizardcancarry(Weapon weapon){
        boolean canCarry  = false
        if weapon is a a staff set canCarry to true
        return canCarry;
    }
 }

public abstract class Player{   

   private List<Weapon> weapons;
   // constructor and OOP goodness left out

   public abstract void add(Weapon weapon);

}


public final class Wizard extends Player{

   @Override 
   public void add(Weapon weapon){

      if(GameRules.verifyifwizardcancarry(weapon){
          // - code to add weapon to inventory
      }
    }
 }

如何验证传递给Weapon GameRules的{​​{1}}实际上是class?从阅读开始,Swordinstanceof的使用被视为代码嗅觉。

我找到了this回答,但它违反了LSP并反对博客所说的内容,它不应该抛出异常,并且不能真正回答我的问题。

2 个答案:

答案 0 :(得分:0)

根据Java dynamic binding and method overriding

当添加一个Sword时,会调用这样的函数,而不是武器的任何其他子项

push_back()

如果只能装备一个(或几个)武器,也可以这样做,但是Overriden功能会给出否定的反应。

答案 1 :(得分:0)

我认为你不能在你的情况下避开public class ActivityPlayer extends YouTubeBaseActivity implements YouTubePlayer.OnInitializedListener { public String DEVELOPER_KEY = "key"; public String YOUTUBE_VIDEO_CODE = "5z-Roo_NpI4"; private static final int RECOVERY_DIALOG_REQUEST = 1; YouTubePlayerView youTubeView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setupActionBar(); setContentView(R.layout.activity_main); youTubeView = (YouTubePlayerView) findViewById(R.id.youtube_player); youTubeView.initialize(DEVELOPER_KEY, this); } private void setupActionBar() { ActionBar actionBar = getSupportActionBar(); if (actionBar != null) { actionBar.setDisplayHomeAsUpEnabled(true); } } @Override public boolean onCreateOptionsMenu(final Menu menu) { getMenuInflater().inflate(R.menu.options_menu, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: finish(); return true; } return true; } @Override public void onInitializationFailure(YouTubePlayer.Provider provider, YouTubeInitializationResult errorReason) { if (errorReason.isUserRecoverableError()) { errorReason.getErrorDialog(this, RECOVERY_DIALOG_REQUEST).show(); } else { Snackbar.make(youTubeView, "There was an error initializing the video player.", Snackbar.LENGTH_LONG).setDuration(5000).show(); } } @Override public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer player, boolean wasRestored) { if (!wasRestored) { player.loadVideo(YOUTUBE_VIDEO_CODE); player.setPlayerStyle(YouTubePlayer.PlayerStyle.CHROMELESS); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == RECOVERY_DIALOG_REQUEST) { getYouTubePlayerProvider().initialize(DEVELOPER_KEY, this); } } @Override public void onBackPressed() { finish(); } private YouTubePlayer.Provider getYouTubePlayerProvider() { return (YouTubePlayerView) findViewById(R.id.youtube_player); } } 运营商。我建议你自己使每一个具体的instanceof负责确定它能携带什么武器。所以删除Player并在玩家之间传播这种逻辑,以便GameRules.verifyifwizardcancarry Wizard检查其武器,其他玩家也这样做。