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

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

一.先来一个策略模式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. crt执行cat命令后乱码

    cat查看二进制文件后所有命令都乱码执行reset即可恢复

  2. 区块链——java实现

    简述 本文主要的内容试一次关于区块链的作业,本次作业中有很多地方和实际的区块链不符合,比如hash,本文实现的区块链只是用了区块本身的hash并没去区分,头部和数据部分.仅供参考学习. 介绍 内容有点 ...

  3. Redis——SpringBoot项目使用Lettuce和Jedis接入Redis集群

    Jedis连接Redis: 非线程安全 如果是多线程环境下共用一个Jedis连接池,会产生线程安全问题,可以通过创建多个Jedis实例来解决,但是创建许多socket会影响性能,因此好一点的方法是使用 ...

  4. 【Wince-DataTable填充ListView】DataTable的数据填充到ListView控件,适用.Net2.0

    在开发WinCE6.0程序的时候,要把DataTable的数据显示到ListView控件上,无法使用绑定, 只能使用循环遍历. 思路:外循环遍历行,内循环遍历列 //DataTable:dt2 //L ...

  5. SQLSERVER 连接常见问题

    1.从索引 0 处开始,初始化字符串的格式不符合规范 解决办法:检查数据库连接字符串 参考链接: https://www.cnblogs.com/guodongsky/archive/2013/04/ ...

  6. Spring Boot 之 Profile --快速搞定多环境使用与切换

    Spring Profile是Spring3引入的概念,主要用在项目多环境运行的情况下,通过激活方式实现多环境切换,省去多环境切换时配置参数和文件的修改,并且Spring profile提供了多种激活 ...

  7. BZOJ 3784: 树上的路径 点分治+二分+set

    很容易想出二分这个思路,但是要想办法去掉一个 $log$. 没错,空间换时间. 双指针的部分错了好几次~ Code: #include <set> #include <queue&g ...

  8. 使用Qt Designer进行布局

    在使用Form之前,需要将Form上的对象放置到布局中.这确保在应用程序中预览或使用Form时,对象将正确显示.在布局中放置对象还可以确保在调整窗体大小时它们也能正确调整大小. 应用和打断布局    ...

  9. Spring Boot教程(二十九)使用JdbcTemplate操作数据库

    使用JdbcTemplate操作数据库 Spring的JdbcTemplate是自动配置的,你可以直接使用@Autowired来注入到你自己的bean中来使用. 举例:我们在创建User表,包含属性n ...

  10. 在spring官网上下载历史版本的spring插件,springsource-tool-suite

    目前spring官网(https://spring.io/tools3/sts/all)上可下载的spring插件只有: ECLIPSE ARCHIVE SIZE 4.9.0 springsource ...