上一篇中我们讲到简单工厂模式有它的弊端,它不好在哪里呢?

我们看到,每次创建场景,我们都需要暴露两个类。。。
这是比较不好的,
可以通过策略模式+简单工厂模式来稍微改造下

一.先来一个策略模式UML图(大话设计模式)

  • Strategy:所有策略的基类
  • StrategyA、StrategyB、StrategyC:三个策略子类
  • Context:上下文,包含一个父类Strategy引用,指向具体的子类策略对象(聚合关系)


二.接下来我们以游戏服务端开发里的生活技能来讲解。这个需求非常适合策略模式。
这里简化下需求:
游戏里生活技能为采集(采矿、采药...)和合成(烹饪、铸造...)两大类。

我们稍微改造下UML图:
1.有一个Context上下文类:
LifeSkillContext2

2.有一个strategy抽象类:
/**
* 生活技能策略基类
* 基类,所以是抽象类,方便子类去不同的实现
* @author lizhibiao
* @date 2019/1/10 21:18
*/
public abstract class AbstractLifeSkillLogic

3.有一个StrategyA子类(这里我们把它也设计为抽象类)
/**
* 采集抽象类
* 这里是抽象类,是因为采集包括采矿、采药。。。
* 方便子类覆写
* @author lizhibiao
* @date 2019/1/10 21:30
*/
public abstract class AbstractAbilityCollectLogic extends AbstractLifeSkillLogic

4.有一个StrategyB子类(这里我们把它也设计为抽象类)
/**
*
* 合成类
* 这里把合成类,也定义为抽象类是因为合成类包括(烹饪、铸造...)
* 方便子类覆写
* @author lizhibiao
* @date 2019/1/10 21:23
*/
public abstract class AbstractAbilityComposeLogic extends AbstractLifeSkillLogic


5.StrategyA类下面挂两个子类分别是采矿和采药
/**
* 采矿
* 继承采集抽象类
* @author lizhibiao
* @date 2019/1/11 14:26
*/
public class AbilityMining extends AbstractAbilityCollectLogic
/**
* 采药
* 继承采集抽象类
* @author lizhibiao
* @date 2019/1/11 14:30
*/
public class AbilityHerbs extends AbstractAbilityCollectLogic

6.同理StrategyB类下面也挂两个子类分别是烹饪和铸造
/**
*
* 烹饪
* 继承合成抽象类
* @author lizhibiao
* @date 2019/1/11 14:37
*/
public class AbilityCooking extends AbstractAbilityComposeLogic
/**
* 铸造类
* 继承合成抽象类
* @author lizhibiao
* @date 2019/1/11 14:43
*/
public class AbilityCasting extends AbstractAbilityComposeLogic



三:依次开始上代码
/**
*
* 生活技能上下文2
* @author lizhibiao
* @date 2019/1/11 15:23
*/
public class LifeSkillContext2
{
private AbstractLifeSkillLogic abstractLifeSkillLogic = null;

public LifeSkillContext2(LifeSkillTypeEnum typeEnum)
{
switch (typeEnum)
{
case MINING:
abstractLifeSkillLogic = new AbilityMining();
break;
case HERBS:
abstractLifeSkillLogic = new AbilityHerbs();
break;
case COOKING:
abstractLifeSkillLogic = new AbilityCooking();
break;
case CASTING:
abstractLifeSkillLogic = new AbilityCasting();
break;
default:
break;
}
}

public AbstractLifeSkillLogic getAbstractLifeSkillLogic()
{
return abstractLifeSkillLogic;
}
}

/**
* 生活技能策略基类
* 基类,所以是抽象类,方便子类去不同的实现
* @author lizhibiao
* @date 2019/1/10 21:18
*/
public abstract class AbstractLifeSkillLogic
{

/**
* 使用生活技能操作
* 抽象方法
*/
public abstract void lifeSkillOperate();

}



/**
* 采集抽象类
* 这里是抽象类,是因为采集包括采矿、采药。。。
* 方便子类覆写
* @author lizhibiao
* @date 2019/1/10 21:30
*/
public abstract class AbstractAbilityCollectLogic extends AbstractLifeSkillLogic
{

@Override
public void lifeSkillOperate()
{
System.out.println("执行采集共有操作------操起镰刀,动手");
}

}

/**
*
* 合成类
* 这里把合成类,也定义为抽象类是因为合成类包括(烹饪、铸造...)
* 方便子类覆写
* @author lizhibiao
* @date 2019/1/10 21:23
*/
public abstract class AbstractAbilityComposeLogic extends AbstractLifeSkillLogic
{

@Override
public void lifeSkillOperate()
{
System.out.println("执行合成公有操作----------烹饪和铸造先点火。。。");
}

}


/**
* 采矿
* 继承采集抽象类
* @author lizhibiao
* @date 2019/1/11 14:26
*/
public class AbilityMining extends AbstractAbilityCollectLogic
{
@Override
public void lifeSkillOperate()
{
super.lifeSkillOperate();

System.out.println("我是采矿--------采矿。。采矿。。。");
}
}
/**
* 采药
* 继承采集抽象类
* @author lizhibiao
* @date 2019/1/11 14:30
*/
public class AbilityHerbs extends AbstractAbilityCollectLogic
{
@Override
public void lifeSkillOperate()
{
super.lifeSkillOperate();

System.out.println("我是采药-------采药。。采药。。");
}
}




/**
*
* 烹饪
* 继承合成抽象类
* @author lizhibiao
* @date 2019/1/11 14:37
*/
public class AbilityCooking extends AbstractAbilityComposeLogic
{

@Override
public void lifeSkillOperate()
{
super.lifeSkillOperate();

System.out.println("我是烹饪----烹饪。。烹饪。。");

}

}
/**
* 铸造类
* 继承合成抽象类
* @author lizhibiao
* @date 2019/1/11 14:43
*/
public class AbilityCasting extends AbstractAbilityComposeLogic
{
@Override
public void lifeSkillOperate()
{
super.lifeSkillOperate();

System.out.println("我是铸造----铸造。。铸造。。");
}
}



四:接下来,我们开始测试
1.添加一个枚举类,如下:
/**
* 生活技能枚举类
* @author lizhibiao
* @date 2019/1/11 14:52
*/
public enum LifeSkillTypeEnum
{
/**
* 采矿
*/
MINING,

/**
* 采药
*/
HERBS,

/**
* 烹饪
*/
COOKING,

/**
* 铸造
*/
CASTING

}


2.开始测试
//采矿  注意这里只暴露一个LifeSkillContext2类
LifeSkillContext2 context = new LifeSkillContext2(LifeSkillTypeEnum.MINING);
AbstractLifeSkillLogic mining = context.getAbstractLifeSkillLogic();
if (null != mining)
{
mining.lifeSkillOperate();
}

System.out.println();

//烹饪 注意这里只暴露一个LifeSkillContext2类
LifeSkillContext2 context2 = new LifeSkillContext2(LifeSkillTypeEnum.COOKING);
AbstractLifeSkillLogic cooking = context2.getAbstractLifeSkillLogic();
if (null != cooking)
{
cooking.lifeSkillOperate();
}
看到没,
确实是只暴露了一个类
输出结果:

但是这也是有弊端的,你发现我们每次都需要new一个上下文类,这样效率太低了。


3.我们来改造下
新建一个上下文类:
**
*
* 生活技能上下文
* @author lizhibiao
* @date 2019/1/10 21:08
*/
public class LifeSkillContext
{
private static AbstractLifeSkillLogic abstractLifeSkillLogic = null;

public static int setLifeSkillLogic(LifeSkillTypeEnum typeEnum)
{
//先置null
abstractLifeSkillLogic = null;

switch (typeEnum)
{
case MINING:
abstractLifeSkillLogic = new AbilityMining();
return 0;
case HERBS:
abstractLifeSkillLogic = new AbilityHerbs();
return 0;
case COOKING:
abstractLifeSkillLogic = new AbilityCooking();
return 0;
case CASTING:
abstractLifeSkillLogic = new AbilityCasting();
return 0;
default:
return -1;
}
}

public static AbstractLifeSkillLogic getLifeSkillLogic()
{
return abstractLifeSkillLogic;
}
}

测试类如下:
/**
* 测试类
* @author lizhibiao
* @date 2019/1/11 15:05
*/
public class Main
{
private static final int SUCESSED = 0;

public static void main(String[] args)
{
//采矿
int result = LifeSkillContext.setLifeSkillLogic(LifeSkillTypeEnum.MINING);
if (result == SUCESSED)
{
LifeSkillContext.getLifeSkillLogic().lifeSkillOperate();
}

System.out.println();

//烹饪
result = LifeSkillContext.setLifeSkillLogic(LifeSkillTypeEnum.COOKING);
if (result == SUCESSED)
{
LifeSkillContext.getLifeSkillLogic().lifeSkillOperate();
}

}
}

测试结果如下:


看到没,这里我们只需要暴露一个LifeSkillContext类,并且我们不需要每次都去new一个上下文!!


java游戏服务器 策略+简单工厂的更多相关文章

  1. java游戏服务器--简单工厂模式

    先来学习下简单工厂模式! 我们知道在游戏里有很多的场景,例如:帮派场景,副本场景,野外场景... 现在我们有这样的需求: 1.我们需要进入帮派场景时---开始执行帮派任务. 2.我们需要进入副本场景时 ...

  2. Java游戏服务器成长之路——感悟篇

    又是一个美好的周末啊,现在一到周末,早上就起得晚,下午困了又会睡一两个小时,上班的时候,早上起来喝一杯咖啡,然后就能高效的工作一整天,然而到了周末人就懒散了,哈哈. 最近刚跳槽,到新公司已经干了有两周 ...

  3. Java游戏服务器搭建

    一.前言 此游戏服务器架构是一个单服的形式,也就是说所有游戏逻辑在一个工程里,没有区分登陆服务器.战斗服务器.世界服务器等.此架构已成功应用在了多款页游服务器 .在此框架中没有实现相关业务逻辑,只有简 ...

  4. Java设计模式2:简单工厂模式

    简单工厂模式 简单工厂模式是类的创建模式,又叫做静态工厂方法模式.简单工厂模式由一个工厂对象决定生产出哪一种产品类的实例. 为什么要使用简单工厂模式 原因很简单:解耦. A对象如果要调用B对象,最简单 ...

  5. Java设计模式学习记录-简单工厂模式、工厂方法模式

    前言 之前介绍了设计模式的原则和分类等概述.今天开启设计模式的学习,首先要介绍的就是工厂模式,在介绍工厂模式前会先介绍一下简单工厂模式,这样由浅入深来介绍. 简单工厂模式 做法:创建一个工厂(方法或类 ...

  6. Java从零开始学十七(简单工厂)

    简单工厂的实现 实现一个计算器:要求输入2个数,和运算符,得到结果 Operation类 package com.pb.demo1; public class Operation { private ...

  7. JAVA基础——设计模式之简单工厂模式

    在阎宏博士的<JAVA与模式>一书中开头是这样描述简单工厂模式的:简单工厂模式是类的创建模式,又叫做静态工厂方法(Static Factory Method)模式.简单工厂模式是由一个工厂 ...

  8. 利用Java反射机制优化简单工厂设计模式

    之前项目有个需求,审批流程的时候要根据配置发送信息:发送短信.发送邮件.当时看到这个就想到要用工厂模式,为什么要用工厂模式呢?用工厂模式进行大型项目的开发,可以很好的进行项目并行开发.就是一个程序员和 ...

  9. Java实验项目三——简单工厂模式

    Program: 请采用采用简单工厂设计模式,为某个汽车销售店设计汽车销售系统,接口car至少有方法print(), 三个汽车类:宝马.奥迪.大众 (属性:品牌,价格),在测试类中根据客户要求购买的汽 ...

随机推荐

  1. [SQLAlchemy] synchronize_session参数

  2. 【CF750E】New Year and Old Subsequence

    题目大意:给定一个长度为 N 的字符串,定义一个字串是"好的",当且仅当字串中含有一个 "2017" 的子序列,且不含有 "2016" 的子 ...

  3. 【洛谷P2915】Mixed Up Cows

    题目大意:给定一个长度为 N 的序列,每个位置有一个权值,现要求重新排列这个序列,使得相邻的权值差的绝对值大于 K,求合法排列的方案数. 题解: 由于 N 很小,应该可以想到状压,考虑如何进行设计状态 ...

  4. spring cache 几个注解解释

    转自https://www.cnblogs.com/fashflying/p/6908028.html 从3.1开始,Spring引入了对Cache的支持.其使用方法和原理都类似于Spring对事务管 ...

  5. windows和linux开机自启动设置

    Windows 1,启动快捷方式   开始>程序>启动 文件夹中拷贝进去需要开机启动的程序快捷方法,此方法需要相应用户登录系统2,注册为服务,设置启动方式为自动   a,    sc命令  ...

  6. [Python之路] HTTP协议复习笔记

    一.HTTP请求的直观了解 我们使用网络调试助手来模拟一个TCP Server,然后使用浏览器来访问对应的IP:Port. 启动后,我们使用谷歌浏览器来访问192.168.1.8:8080: 我们可以 ...

  7. jquery focus()方法 语法

    jquery focus()方法 语法 作用:当元素获得焦点时,发生 focus 事件.大理石平台价格 触发focus事件语法:$(selector).focus() 将函数绑定到focus事件语法: ...

  8. 计算机网络(六),UDP报文段详解

    目录 1.UDP作用 2.UDP报文段详解 六.UDP报文段详解 1.UDP作用 (1)面向非连接 (2)不维护连接状态,支持同时向多个客户端传送相同的消息 (3)报文段报头只有8个字节,格外开销较小 ...

  9. Python实用黑科技——找出序列里面出现次数最多的元素

    需求: 如何从一个序列中快速获取出现次数最多的元素. 方法: 利用collections.Counter类可以解决这个问题,特别是他的most_common()方法更是处理此问题的最快途径.比如,现在 ...

  10. Moco 详解

    一.下载及安装: 运行环境: JAVA环境 linux 下载地址:https://github.com/dreamhead/moco 下载下来的是一个jar包,如:moco-runner-0.12.0 ...