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

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

一.先来一个策略模式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. zencart后台隐藏配置菜单configuration.php?gID=6

    zencart后台隐藏配置菜单-模块选项 http://域名/后台/configuration.php?gID=6

  2. hive创建分区表

    #创建分区表CREATE TABLE if not exists data_center.test_partition (id int,name string,age int)PARTITIONED ...

  3. java代码调用exe(cmd命令)

    public class ShellCommand{    public static void execCmd(String cmd, boolean wait)    {        execC ...

  4. office visio

    画 流程图软件 UML 是否要用做类图.时序图?????

  5. 阿里云-docker安装mysql

    1.检查内核版本,必须是3.10及以上 uname ‐r 2.安装docker yum install docker 3.输入y确认安装 4.启动docker:service docker start ...

  6. pidstat 命令详解(转载)

    转自https://www.jianshu.com/p/3991c0dba094 pidstat 概述 pidstat是sysstat工具的一个命令,用于监控全部或指定进程的cpu.内存.线程.设备I ...

  7. Kattis - itsamodmodmodmodworld It's a Mod, Mod, Mod, Mod World (类欧几里得)

    题意:计算$\sum\limits_{i=1}^n[(p{\cdot }i)\bmod{q}]$ 类欧模板题,首先作转化$\sum\limits_{i=1}^n[(p{\cdot}i)\bmod{q} ...

  8. k8spod资源的基础管理操作

    pod是k8s api中的核心资源类型,它可以定义在json或yaml格式的资源清单中,由资源管理命令进行陈述式或声明式管理.创建时,用户可通过create或apply命令将请求提交到apiserve ...

  9. 【Druid】-Druid数据源加密数据库密码配置

    1.数据库配置文件添加配置 <property name="filter" value="config"> <property name=&q ...

  10. 【leetcode】1234. Replace the Substring for Balanced String

    题目如下: You are given a string containing only 4 kinds of characters 'Q', 'W', 'E' and 'R'. A string i ...