Java接口的游戏实战应用

本文介绍了Java接口的基础知识,强调了接口作为规范集合和提高代码灵活性的重要性。在实战部分,通过实体接口和Function/Manager接口的示例,展示了如何在游戏开发中使用接口来规范业务逻辑,实现数据验证、分发和逻辑执行。FunctionAdapter用于注册并管理实现了IFunction接口的子类,从而统一处理相关业务操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一)接口简介

      Java接口是一系列方法的声明,是一些方法特征的集合,同时也是一种比抽象类要高级的规范,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。

两个类中的两个类似的功能,调用他们的类动态的决定一种实现,那他们提供一个抽象父类,子类分别实现父类所定义的方法。

问题的出现:Java是一种单继承的语言,一般情况下,哪个具体类可能已经有了一个超类,解决是给它的父类加父类,或者给它父类的父类加父类,直到移动到类等级结构的最顶端。这样一来,对一个具体类的可插入性的设计,就变成了对整个等级结构中所有类的修改。

在一个等级结构中的任何一个类都可以实现一个接口,这个接口会影响到此类的所有子类,但不会影响到此类的任何超类。此类将不得不实现这个接口所规定的方法,而其子类可以从此类自动继承这些方法,当然也可以选择置换掉所有的这些方法,或者其中的某一些方法,这时候,这些子类具有了可插入性(并且可以用这个接口类型装载,传递实现了他的所有子类)。

我们关心的不是那一个具体的类,而是这个类是否实现了我们需要的接口。

接口提供了关联以及方法调用上的可插入性,软件系统的规模越大,生命周期越长,接口使得软件系统的灵活性和可扩展性,可插入性方面得到保证。

Java接口(以及抽象类)一般用来作为一个类型的等级结构的起点。

如果一个类已经有了一个主要的超类型,那么通过实现一个接口,这个类可以拥有另一个次要的超类型,这种次要的超类型叫做混合类型。

二)实战应用

1)简单规范实例

1】实体接口

package com.xiu.interfaces;

import java.io.Serializable;

/**
 *实体接口
 *
 * @author xiu
 * @version 2017年8月3日 上午11:00:05 
 */
public interface IEntity<K extends Serializable> {
	/**
	 * 获取主键
	 * @return
	 */
	K getId();
	
}
2】实现

@Entity(tableName = "backpack", comment = "背包")
public class BackpackEntity implements IEntity<Long> {

	@Id
	@Column(name = "id", comment = "玩家id")
	private long id;

	@Column(name = "grid_content", length = 20000, comment = "背包格子")
	private List<BackpackGrid> grids = new ArrayList<>();

	@Override
	public Long getId() {
		return id;
	}

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

	public List<BackpackGrid> getGrids() {
		return grids;
	}

	public void setGrids(List<BackpackGrid> grids) {
		this.grids = grids;
	}

}

@Entity(tableName = "notice", comment = "公告表")
public class NoticeEntity  implements IEntity<Integer>{
	
	@Id
	@Column(name = "id", comment = "公告编号")
	private int id;
	
	@Column(name = "notice_type", comment = "公告类型 1跑马灯,2活动公告,3登录公告")
	private int noticeType;
	
	@Column(name = "title", length = 1000 , comment = "标题")
	private String title;
	
	@Column(name = "content", length = 63001 , comment = "内容")
	private String content;
	
	@Column(name = "stime", comment = "公告展示开始时间(秒)")
	private int stime;
	
	@Column(name = "etime", comment = "公告展示结束时间(秒)")
	private int etime;
	
	@Column(name = "diffTime", comment = "播放时间间隔(以秒为单位)")
	private int diffTime;
	
	@Column(name = "level", comment = "数值越大,优先级越高")
	private int level;
	
	@Column(name = "status", comment = "公告状态(0正常,1删除)")
	private StatusType status;

	@Override
	public Integer getId() {
		return this.id;
	}

2)消息推送模块实现

1】接口规范

主要规范方法:发送推送请求、单条、多条消息推送

package com.xiu.push;

import java.util.Collection;

/**
 *
 *
 * @author xiu
 * @version 2017年8月3日 上午11:29:24 
 */
public interface IPush {

	/**
	 * 发送推送请求
	 * @param dPushNotification
	 * @throws Exception
	 */
	void send(DPushNotification dPushNotification) throws Exception;
	
	/**
	 * 单播推送
	 * @param role
	 * @param msgId
	 * @param args
	 * @throws Exception
	 */
	void unicastPush(Role role, int msgId, Object... args) throws Exception;
	
	/**
	 * 单播推送
	 * @param role
	 * @param msg
	 * @param ticker
	 * @param title
	 * @throws Exception
	 */
	void unicastPush(Role role, String msg, String ticker, String title) throws Exception;
	
	/**
	 * 列播推送
	 * @param roles
	 * @param msgId
	 * @param args
	 * @throws Exception
	 */
	void listcastPush(Collection<Role> roles, int msgId, Object...args) throws Exception;

}

Role为玩家实体类,DPushNotification为推送消息数据结构

package com.xiu.push;

/**
 *推送消息数据结构
 *
 * @author xiu
 * @version 2017年8月3日 上午11:30:16 
 */
public class DPushNotification {
	
	/**角色id*/
	private long rid;
	/***/
	private long extendsionId;
	/**消息内容*/
	private String msgContext="";
	/**推送时间*/
	private int pushTime;
	/**是否阅后即删*/
	private boolean isRemove;
	/**消息类型*/
	private int type;
	/**标题*/
	private String title;
	/**事件类型*/
	private int eventId;
	
	//对应getter、setter
}

2】接口实现

@Component
public class PushService implements IPush{
	
	//TODO
}


3)Function/Manager接口

在实际开发中Function或者Manager都是具体的业务逻辑实现类,相当于MVC分层模式中的Controller,负责数据的验证分发等,或者执行特定的逻辑。

1】IFunction接口

package com.xiu.function;

import com.xiu.push.Role;

/**
 *游戏逻辑接口
 *
 * @author xiu
 * @version 2017年8月3日 上午11:49:59 
 */
public interface IFunction {

	/**
	 * 服务器启动时对游戏库的处理
	 */
	public void handleOnServerStart();
	/**
	 * 服务器启动时对日志库的处理
	 */
	public void handleOnServerStartLog();
	/**
	 * 在角色登陆的时候处理
	 * @param role
	 */
	public void handleOnRoleLogin(Role role);
	/**
	 * 在角色下线的时候处理
	 * @param role
	 */
	public void handleOnRoleLogout(Role role);
	

	/**
	 * 凌晨时候的处理
	 */
	public void handleOnNextDay() ;
	
	/**
	 * 服务器准备关闭前调用
	 */
	public void handleOnServerShutdown();
	
}
该接口主要逻辑方法有五个:在服务器启动、关闭,角色登录、下线,跨天时执行
同理,战斗逻辑接口、道具逻辑接口也会有相关的规范设计。

2】FunctionAdapter逻辑索引

所有子类游戏逻辑只要继承基类或父类接口,就拥有父类接口的方法规范或者父类属性。

/**
 *公用逻辑处理
 *
 * @author xiu
 * @version 2017年8月3日 下午12:01:49 
 */
public class FunctionAdapter implements IFunction {

	public FunctionAdapter() {
		FunctionManager.register(this);
	}
	
	@Override
	public void handleOnServerStart() {
		//default handle nothing
	}
	
	@Override
	public void handleOnServerStartLog() {
		//default handle nothing
	}

	@Override
	public void handleOnRoleLogin(Role role) {
		//default handle nothing
	}

	@Override
	public void handleOnRoleLogout(Role role) {
		//default handle nothing
	}
	
	@Override
	public void handleOnNextDay() {
		//default handle nothing
	}

	@Override
	public void handleOnServerShutdown() {
		// TODO Auto-generated method stub
	}
}
观察上面发现多了一个构造方法FunctionAdapter(),这种用法很常见,也是Java多态特性的应用,只需要父类实现了该功能,子类只要继承于此并且重写这些方法就能拥有这些特性,而不需要单独去实现某些逻辑方法。

3】FunctionAdapter()的作用是注册继承于IFunction接口的所有子类到FunctionManager中,然后通过Funciton管理器统一处理规范方法。

package com.xiu.function;

import java.util.HashMap;
import java.util.Map;

import com.xiu.push.Role;

/**
 *公用逻辑管理器
 *
 * @author xiu
 * @version 2017年8月3日 下午1:52:52 
 */
public class FunctionManager {

	private static Map<Class<? extends IFunction>, IFunction> functionMap = new HashMap<Class<? extends IFunction>, IFunction>();
	
	/**
	 * 把所有继承于IFunction接口的类注册到functionMap中,通过Funciton管理器统一管理这些子类逻辑
	 * @param function
	 */
	public static void register(IFunction function) {
		if (functionMap.containsKey(function.getClass())) {
			throw new RuntimeException("Duplicate function register "+function.getClass().getSimpleName());
		}
		functionMap.put(function.getClass(), function);
	}
	
	/**
	 * 处理服务器启动
	 */
	public static void handleOnServerStart() {
		doHandleOnServerStart();
	}

	/**
	 * 处理服务器启动时对游戏类的处理
	 */
	private static void doHandleOnServerStart() {
		for (IFunction handler : functionMap.values()) {
			try {
				handler.handleOnServerStart();
				System.out.println("doHandleOnServerStart");
			} catch (Exception e) {
				//LogUtil.error(e);
				System.err.println("have exception on do handleOnServerStart" + e);
			}
		}
	}
	
	/**
	 * 玩家登录时对游戏类的处理
	 * @param role
	 */
	public static void doHandleOnRoleLogin(Role role) {
        for (IFunction handler : functionMap.values()) {
            try {
                handler.handleOnRoleLogin(role);
            } catch (Exception e) {
               // LogUtil.error(e);
            }
        }
	}
	
	/**
	 * 玩家离线时处理
	 * @param role
	 */
	public static void doHandleOnRoleLogout(Role role) {
		if (role == null) {
			return;
		}
		for (IFunction handler : functionMap.values()) {
			try {
				handler.handleOnRoleLogout(role);
			} catch (Exception e) {
				//LogUtil.error(e);
			}
		}
	}

	/**
	 * 每天凌晨0点处理
	 */
	public static void doHandleOnNextDay() {
        for (IFunction handler : functionMap.values()) {
            try {
                handler.handleOnNextDay();
            } catch (Exception e) {
                //LogUtil.error(e);
            }
        }
	}
	
}
通过FunctionManager在服务器启动、关闭,玩家登陆、离线,跨天的时候插入对应的逻辑方法,继承于IFunciton的Funciton子类只要实现上面那些注册了的方法就能拥有对应的特性。
4】实例使用

package com.xiu.function.activity;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import com.xiu.function.FunctionAdapter;
import com.xiu.push.Role;

/**
 *活动逻辑
 *
 * @author xiu
 * @version 2017年8月3日 下午2:21:56 
 */
public class ActivityFunction extends FunctionAdapter {

	/** 缓存玩家对应的活动列表 Map<rid, Map<aId,ActivityRole>> */
	private ConcurrentHashMap<Long, Map<Long, ActivityRole>> activityRoleCacheMap = new ConcurrentHashMap<>();

	/** 缓存活动列表 Map<aid, activity> */
	private ConcurrentHashMap<Long, Activity> activityCacheMap = new ConcurrentHashMap<>();

	
	@Override
	public void handleOnRoleLogout(Role role) {
		activityRoleCacheMap.clear();
	}

	@Override
	public void handleOnServerShutdown() {
		activityCacheMap.clear();
		activityRoleCacheMap.clear();
	}
	
}


























评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值