• [多态设计模式]枚举


    方案1:

    背景:

    游戏服务器中,多态可以说体现的淋漓尽致。

    如:

    1.开启条件。有的系统是根据玩家等级,有的是根据通关第几关。

    2.商店可能有不同类型的商店。

    3.任务系统中,不同的计数类型,不同的任务目标类型。

    4.功能开启中,不同的系统开启条件不同。

    ....

    稍微复杂一点的系统都会涉及到多态。

    我们往往需要采用一种一致的接口去处理,这样子可以避免冗余代码。但是他们需要的数据却不同。

    经过我的实践,我觉得一种比较好的写法如下:

    ETest.java  // 枚举所有的类型

    1. package org.example.enumDuoTai;
    2. import org.example.enumDuoTai.data.ATestData;
    3. import org.example.enumDuoTai.data.BTestData;
    4. import org.example.enumDuoTai.data.ITestData;
    5. public enum ETest {
    6. A {
    7. @Override
    8. public void test(ITestData data) {
    9. ATestData aTestData = data.get();
    10. System.out.println("roleId="+ aTestData.getRoleId() + " a=" + aTestData.getA());
    11. }
    12. },
    13. B {
    14. @Override
    15. public void test(ITestData data) {
    16. BTestData bTestData = data.get();
    17. System.out.println("sn="+ bTestData.getSn() + " B=" + bTestData.getB());
    18. }
    19. },
    20. ;
    21. public abstract void test(ITestData data);
    22. }

    ITestData.java // 数据接口

    1. package org.example.enumDuoTai.data;
    2. @SuppressWarnings("all")
    3. public interface ITestData {
    4. default T get(){
    5. return (T)this;
    6. }
    7. }

    ATestData.java // 数据参数实现1

    1. package org.example.enumDuoTai.data;
    2. import lombok.AllArgsConstructor;
    3. import lombok.Data;
    4. @Data
    5. @AllArgsConstructor
    6. public class ATestData implements ITestData{
    7. private long roleId;
    8. private int a;
    9. }

    BTestData.java // 数据参数实现

    1. package org.example.enumDuoTai.data;
    2. import lombok.AllArgsConstructor;
    3. import lombok.Data;
    4. @Data
    5. @AllArgsConstructor
    6. public class BTestData implements ITestData{
    7. private int sn;
    8. private String b;
    9. }

    Main.java

    1. package org.example.enumDuoTai;
    2. import org.example.enumDuoTai.data.ATestData;
    3. import org.example.enumDuoTai.data.BTestData;
    4. public class Main {
    5. public static void main(String[] args) {
    6. ETest.A.test(new ATestData(4097, 1));
    7. ETest.B.test(new BTestData(1001, "jn"));
    8. }
    9. }
    10. /*
    11. roleId=4097 a=1
    12. sn=1001 B=jn
    13. */

    总结:

    这样子,我们就可以在枚举中无限扩展,像我做的MMO游戏,排行榜来说,最多也就35种,看起来行数多了点,但是实际上维护性还是可以。这种枚举的多态,实现比较简单。

    这样子通过接口,让所有的操作都是强类型的,是比较简单的。

    而且枚举有values,天然实现了遍历,也就是工厂模式。

    --------------

    方案2:

    背景:

    我现在要设计一个复杂的属性系统,输入参数是多变的,导致我很难搞,大部分来源都是:PlayerEntity,但是有的来源可能是:国王等,导致输入参数差异是很大的,之前做的卡牌游戏,都是: 只有一个Role上下文就可以了。 

    后面在mt项目中,发现了IxxxData(get方法)+多种实现进行实现。

    现在看到了通过泛型+子类 来构造上下文。

    ITest.java

    1. package org.example.testGeneric;
    2. public interface ITest<T> {
    3. int test(T t);
    4. }

    TestAddImpl.java

    1. package org.example.testGeneric;
    2. public class TestAddImpl implements ITest {
    3. private int a;
    4. private int b;
    5. public TestAddImpl(int a, int b) {
    6. this.a = a;
    7. this.b = b;
    8. }
    9. @Override
    10. public int test(TestAddImpl testA) {
    11. return a + b;
    12. }
    13. }

    TestSubImpl.java

    1. package org.example.testGeneric;
    2. public class TestSubImpl implements ITest {
    3. private String str;
    4. private int age;
    5. public TestSubImpl(String str, int age) {
    6. this.str = str;
    7. this.age = age;
    8. }
    9. @Override
    10. public int test(TestSubImpl testSub) {
    11. return (str == null || str.isEmpty()) ? 0 : str.length() + age;
    12. }
    13. }

    Main.java

    1. package org.example.testGeneric;
    2. public class Main {
    3. public static void main(String[] args) {
    4. test(new TestAddImpl(1, 2));
    5. test(new TestSubImpl("jn", 18));
    6. }
    7. public static void test(ITest iTest) {
    8. System.out.println(iTest.test(iTest));
    9. }
    10. }

  • 相关阅读:
    ConcurrentHashMap (jdk1.7)源码学习
    Kotlin协程基础-CoroutineContext
    为什么自研官网系统,比以往面对更大挑战?
    NestedConfigurationProperty的作用
    LeetCode——半有序排列
    定时任务job (现成直接用)
    【信息奥赛实训】Week1——STL 与基础数据结构专题训练
    终端关闭或用户退出登录,Linux命令继续运行
    连接局域网的mysql数据库
    JavaScript之BOM对象操作窗口大小、加载、定时器、this指向、同步与异步、location对象、navigator对象、history对象
  • 原文地址:https://blog.csdn.net/themagickeyjianan/article/details/133278509