lpc 设计模式运用(一)

前言

对于当前很多lpc,因为年代的问题,目前很多流传下来的lib在代码结构设计上可能存在可以继续优化的可能性,所以写这篇贴子就是简单的介绍一下如何将时代发展下来更新的一些设计模式从设计方案,到代码结构灵活的运用到lpmud开发上,笔者可能会不定时更新,由于笔者可能存在功力不足的情况,所以所有代码和方案仅供参考。

简介

LPC 是一种基于面向对象编程的语言,因此可以使用许多常见的设计模式来提高代码的效率和可维护性。以下是一些常见的可以应用于lpc游戏开发的设计模式:

  1. 单例模式:用于确保一个类只有一个实例,并提供全局访问点。

  2. 工厂模式:用于创建对象,将对象的创建和使用分离开来,提高代码的灵活性和可扩展性。

  3. 观察者模式:用于实现对象之间的消息传递,当一个对象发生变化时,通知其他对象进行相应的处理。

  4. 装饰器模式:用于动态地给对象添加新的功能,而不需要修改原有的代码。

  5. 适配器模式:用于将一个类的接口转换成另一个类的接口,使得原本不兼容的类可以协同工作。

  6. 策略模式:用于将算法的实现和使用分离开来,提高代码的灵活性和可扩展性。

  7. 模板方法模式:用于定义一个算法的框架,将算法的具体实现延迟到子类中。

  8. 命令模式:用于将一个请求封装成一个对象,使得请求的发送者和接收者解耦。

以上是一些常见的设计模式,它们可以帮助开发者提高代码的效率和可维护性。在实际编程中,需要根据具体的需求和设计来选择合适的设计模式。

装饰器模式--套装运用

一套功能模块从到功能方案设计到进行开发之前,通常会需要进行设计模式的选择,也就是我们准备进行开发开发的其中一个环节,我们可以理清一下套装在几个基本的功能设计需要去

1.可批量化

指套装可以批量进行生产,并且分配给使用者,每一件套装部位的具体实习对象应该相互独立而互不冲突。

2.可组合化

指套装可以进行部件的组合,套装拥有部件组合效果,穿戴一定数量的套装部件就可以触发。所以我们一般需要定义min_number最小生效数和max_number最大生效数。

所以我们举例一个简单的开发设计方案

套装文档

1.套装装饰类(用于装饰所有套装)

-- 当装备一件装备的请求发起时,默认调用该类,该类会自行判断一件装备是否可以生成套装效果。

2.部件套装装饰类 (装饰)

-- 用于装饰单个部件的生效属性,当一个部件被生产时,默认调用该类进行装饰,该类只装饰防御和攻击等数值。

3.基本装备类 (抽象)

4.外部装备数据存储类

套装的名称:各类部件生效的属性, -- 其他辅助属性

  • min-number 最小触发件数

  • max-number 最大触发件数

-- 记录了所有套装的属性,当装饰器准备装饰时调用这个类进行数据查取,进行动态数据查询。

5.具体装备类 (具体被装饰的类)

该类只需要定义依据于那个套装,自动装饰。

基本装备类应该拥有基本的数据,然后多余的数据被装饰器类所装饰。

默认带的属性属性

--armor_type 定义了装备的类型 (由基本装备类决定)

--armor_prop/armor 定义了防具的防御力 (由装饰类决定)

--combination_equip_name 套装名称 (由具体装备类决定)

简单的代码测试

部件装饰类

// 部件装饰类
#define EQUIP_BASE "/adm/special_ob/combination_equip/basic/base"

int set_attribute(object equip)
{
    mapping data;

    // 查询是否有combination_equip属性
    if (!equip->query("combination_equip_name"))
    {
        return 0;
    }

    // 查询是否有这个套装,check_equip_name
    if (!EQUIP_BASE->check_equip_name(equip->query("combination_equip_name")))
    {
        return 401;
    }

    // 查询是否有这个套装的这个部件,check_equip_part
    if (!EQUIP_BASE->check_equip_part(equip->query("combination_equip_name"), equip->query("armor_type")))
    {
        return 402;
    }

    //设定属性
    data = EQUIP_BASE->get_equip_attribute(equip->query("combination_equip_name"), equip->query("armor_type"));

    // 遍历data,set
    foreach (string key in keys(data))
    {
        equip->set(key, data[key]);
    }

    return 1;

}

外部存储类

// 套装数据查询类
// 使用注释------------------来分割不同的套装,增加可读性
mapping equip_attribute_data_list = ([
    // ----------------------------
    "萌新套装":([
        "armor":([
            "armor_prop/armor":100,
            "str":2,
        ]),
        "min_number":1,
        "max_number":1,
    ]),
    // ----------------------------
]);

// 返回一个套装某个部位的属性
mapping get_equip_attribute(string equip_name,string equip_part)
{
    mapping equip_attribute = equip_attribute_data_list[equip_name][equip_part];
    return equip_attribute;
}

// 查询是否有某个套装,有返回1,使用undefinedp
int check_equip_name(string equip_name)
{
    if(undefinedp(equip_attribute_data_list[equip_name]))
    {
        return 0;
    }

    return 1;
}

// 查询一个套装是否有某个部位,有返回1,使用undefinedp
int check_equip_part(string equip_name,string equip_part)
{
    if(undefinedp(equip_attribute_data_list[equip_name][equip_part]))
    {
        return 0;
    }

    return 1;
}

具体装备类

只需要定义套装的名称,如果需要抽取其他的基本属性,可以剥离加入外部存储类,例如vaule,unit如果认为有必要,可以加入到外部存储类中交给装饰类装饰。

// tiejia.c 铁甲
//

#include <armor.h>

inherit ARMOR;

void create()
{
    set_name("萌新铁甲", ({ "mengxin jia" }) );
    set_weight(20000);
    if( clonep() )
        set_default_object(__FILE__);
    else {
        set("unit", "件");
        set("material", "steel");
        set("value", 2000);
        set("combination_equip_name", "萌新套装");
    }

    setup();
}

用于测试的测试类

int main(object me, string arg)
{

    object ob;
    int a;

    ob = new("/adm/special_ob/combination_equip/entity/mengxin/tiejia");
    a = "/adm/special_ob/combination_equip/basic/equip_component"->set_attribute(ob);

    write(sprintf("%O-----------test------------:%O,状态:%O\n",ob->query("armor_type"),ob->query("armor_prop/armor"),a));
    destruct(ob);
    return 1;
}

测试效果

file

京ICP备13031296号-4