热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

关于OOP思想和该如何设计一个类

现在我的项目中,需要将一些字符串转换为预先定义好的整形类型.比如将车牌颜色进行转换的功能如下:if(strcmp(pszPlate,未识别)0)
现在我的项目中,需要将一些字符串转换为预先定义好的整形类型.
比如将车牌颜色进行转换的功能如下:
       if (strcmp(pszPlate, "未识别") == 0)
       {
           return emUnKnowColour; //整型值使用枚举表示
//}
//else if (strcmp(pszPlate, "黑") == 0)
//{
// return emPlateColour_Black;

//}
//else if (strcmp(pszPlate, "蓝") == 0)
//{
// return emPlateColour_Blue;

//}
........

此外还有将车身颜色字符串转换为整形,过车类型(大车,中型车,小车等)转为整形。
这里要是按照C的面向过程的思路,就是一个功能一个函数。
但是现在想练就OOP技能,觉得还是多用面向对象比较好。就封装了一个数据字典的class,每个函数都是静态的(满足线程安全),这样需要转换的时候只要CDataDictionary::GetXXXX()就可以了。
class CDataDictionary
{
public:
static int GetPlateColourValueByText(char *pszPlate);
static int GetVehicleTypeByText(char *pszVehicleType);
static int GetCarColourByText(char *pszCarColour);
static int GetContorlTypeByText(char *pszContorlType);
static int GetIllegalTypeByText(char *pszIllegaType);
};

这里感觉静态方法调用比较别扭,如果不用静态方法则在转换的时候需要创建对象,利用 object.GetXXX()
哪种方法更好呢?

同时问题也来了,考虑到以后的扩展。如果项目后期添加其他类型的转换,就要在这个类中添加一个静态方法,但是这和封闭--开发原则是矛盾的(对扩展是开发的,对修改是封闭的)。
所以OOP的思想是先建立一个抽象的接口类如:
class Transform
{
    virtual int TransTextToValue(char *pszText) = 0;
}
然后转换车牌就添加一个车牌转换类,再添加一个过车转换类....如果需要扩展转换,添加子类就可以了。
而且这里可以运用策略模式。

个人觉得这样一个功能,添加了很多代码,实在,实在不情愿。。觉得第一种做法也可以,但是觉得第二种做法似乎更好,欢迎大家讨论拍砖。。。
同时在C++开发的时候,筒子们是否都OOP?还是觉得函数来的更直接,就面向过程了

23 个解决方案

#1


顶起来。。。

#2


想的太多了。再好的东西,也不能滥用。简单的一个字典功能,实在没必要大动干戈。

#3


引用 2 楼 happyparrot 的回复:
想的太多了。再好的东西,也不能滥用。简单的一个字典功能,实在没必要大动干戈。

是啊,有点头痛,想就像第一种实现那样做,但是又怕以后别人看了我的代码,觉得这个家伙太水。。。。版主平时怎么做的,是喜欢用函数还是OOP

#4


我的系统中也有过字典功能。通过编码查名称,或者其它相关信息。首先这些信息放置在一个文件中,不管是二进制还是文本。然后对应有一个字典类。用类是因为对于字典文件需要提供多种查询函数,而不只是一个。
当然,这是在字典文件比较少的时候的处理。如果比较多的话,倒是需要进行优化考虑。
不过对于设计模式也好,各种原则也好,我觉得要看情况使用。并非模式的就好,原则的就好。对我来说,主要看后续的扩展的变化的可控度来选择合理的方式。

#5


引用 4 楼 happyparrot 的回复:
我的系统中也有过字典功能。通过编码查名称,或者其它相关信息。首先这些信息放置在一个文件中,不管是二进制还是文本。然后对应有一个字典类。用类是因为对于字典文件需要提供多种查询函数,而不只是一个。
当然,这是在字典文件比较少的时候的处理。如果比较多的话,倒是需要进行优化考虑。
不过对于设计模式也好,各种原则也好,我觉得要看情况使用。并非模式的就好,原则的就好。对我来说,主要看后续的扩展的变化的可控度来选择合理的方式。

恩,多谢了

#6


如果是我的话我会选择前者,每个函数对应一个功能,函数之间相对独立没什么耦合,后期增加功能也就增加个函数,不会有什么太大影响。套了设计模式加了一堆类,每个类就那么1,2个函数,感觉有点复杂,刻意套用模式的痕迹。菜鸟之言有什么错误的请各位指正

#7


莫非LZ和我一个公司的?
LZ可以这样

class CDataDictionary    //该类管理字典数据
{
}

class Command           //该类作为基类管理行为
{
   Command(CDataDictionary& data);
   int Translate(char* sz)=0;
}

class ColorCommad:public command
{
}

这样你扩展字典数据以及查询行为时都很方便

#8


引用 6 楼 dahaiI0 的回复:
如果是我的话我会选择前者,每个函数对应一个功能,函数之间相对独立没什么耦合,后期增加功能也就增加个函数,不会有什么太大影响。套了设计模式加了一堆类,每个类就那么1,2个函数,感觉有点复杂,刻意套用模式的痕迹。菜鸟之言有什么错误的请各位指正

大侠太谦虚了,我也这么觉得。。。没看过OOP高手是怎么写代码的。。。以后打算多看看,借鉴下

#9


引用 7 楼 My_ID_is_NULL 的回复:
莫非LZ和我一个公司的?
LZ可以这样

class CDataDictionary    //该类管理字典数据
{
}

class Command           //该类作为基类管理行为
{
   Command(CDataDictionary& data);
   int Translate(char* sz)=0;
}

class ColorCommad:public command
{
}

这样你扩展字典数据以及查询行为时都很方便

都是安防的吧,你哪家?

#10


引用 9 楼 xiaoxiaoyu85 的回复:
Quote: 引用 7 楼 My_ID_is_NULL 的回复:

莫非LZ和我一个公司的?
LZ可以这样

class CDataDictionary    //该类管理字典数据
{
}

class Command           //该类作为基类管理行为
{
   Command(CDataDictionary& data);
   int Translate(char* sz)=0;
}

class ColorCommad:public command
{
}

这样你扩展字典数据以及查询行为时都很方便

都是安防的吧,你哪家?

海康

#11


你们在张江吧,兄弟科达。。

#12


认识

引用 10 楼 My_ID_is_NULL 的回复:
Quote: 引用 9 楼 xiaoxiaoyu85 的回复:

Quote: 引用 7 楼 My_ID_is_NULL 的回复:

莫非LZ和我一个公司的?
LZ可以这样

class CDataDictionary    //该类管理字典数据
{
}

class Command           //该类作为基类管理行为
{
   Command(CDataDictionary& data);
   int Translate(char* sz)=0;
}

class ColorCommad:public command
{
}

这样你扩展字典数据以及查询行为时都很方便

都是安防的吧,你哪家?

海康

你们在张江吧,兄弟科达。。 你们公司还是认识一些人的

#13


类内置一个私有的成员变量map,构造函数时进行初始化,通过set/get接口访问。或者使用表驱动。仅供参考。

#14


引用 13 楼 ystudy 的回复:
类内置一个私有的成员变量map,构造函数时进行初始化,通过set/get接口访问。或者使用表驱动。仅供参考。

没懂,是map吧,string是字典,int是字典类型枚举,这里表驱动也没理解,是map[主键]吗?
string作为map的主键查找时效率会受影响吗?
问的比较弱。。。

#15


class CData
{
public:
CData()
{
//硬编码初始化m_Data;
}

CData(string strFile)
{
//从例如xml配置文件或例如sqlite3数据库读取数据到m_Data;
}

virtual ~CData()
{
}

public:
Set(string strKey, int iData);

Get(string strKey, int &iData);

int Get(string strKey);

private:
map m_Data;
};


这样考虑不知是否合理,如上仅供参考。
不是太清楚stl内部机制,string作为主键在map中查找时可能存在字符串比较,如果这样的话效率应该有所影响,不知改用hash_map是否较好。
关于表驱动详见http://baike.baidu.com/link?url=aiaxofz3hGyB0xoJP-mp5nGADTIVK2-rW3_LBf0Nma8j5bHJNlmRCzy0QCA_NjoNLHtonnYjHl4Dyoh5I9GEma 表驱动常用于避免写很多的if或switch。

#16


借楼一用,刚开始涉及安防,想请教一些问题,能否请xiaoxiaoyu85,winginsky二位有安防经验的前辈,有空的时候帮忙看看此贴。
http://bbs.csdn.net/topics/390588864?page=1#post-395544850

#17


顶起来。。。。

#18


顶起来。。。

#19


对于一些小项目没有必要用OOP的思想,相当过程更简单一些

#20


对于LZ的问题,map已经足够,不需要硬套设计模式。否则就本末倒置了。
很多比较有用的设计模式关注的是模块之间的解耦,比如Observer。至于动态的行为替换,见仁见智,策略模式不一定就完美,表驱动法也不一定坏。
直接上代码吧,LZ可以参考:

struct ColorMap
{
public:
    static int Get(const std::string& key)
    {
        static ColorMap color_map;
        auto it = color_map.map_.find(key);
        if (color_map.map_.end() == it)
        {
            return UNKNOWN;
        }
        return it->second;
    }
private:
    ColorMap()
    {
        map_["未识别"] = UNKNOWN;
        map_["黑"] = BLACK;
        map_["蓝"] = BLUE;
        ...
    }
private:
    std::map map_;
}

使用起来就是简单的一句: int color = ColorMap::Get("蓝");
使用表驱动法,当映射项目有变化的时候,只需要修改map_初始化的地方即可,也就是一行代码的事情,其他地方不需要动。
使用策略模式,呵呵,首先你需要修改子类(子策略),可能是增加,可能是减少,也可能是变动;然后你还要修改从key到value之间的映射代码(怎么映射,看你怎么实现了,手法很多),这样你相当于做了很多本来可以省去的工作。
实际上这个问题的焦点本来就应该只是“映射关系”,也就是map_初始化的那段代码而已。使用表驱动法可以直入问题要害,一针见血。扩展性也不输策略模式。

这里我并不是反对设计模式,而是要提醒在使用模式的时候,一定要注意使用场景。LZ如果细心的话,应该已经注意到我举的例子里头实际上已经包含了一个很有名的模式 ^_^

#21


引用 20 楼 yao050421103 的回复:
对于LZ的问题,map已经足够,不需要硬套设计模式。否则就本末倒置了。
很多比较有用的设计模式关注的是模块之间的解耦,比如Observer。至于动态的行为替换,见仁见智,策略模式不一定就完美,表驱动法也不一定坏。
直接上代码吧,LZ可以参考:

struct ColorMap
{
public:
    static int Get(const std::string& key)
    {
        static ColorMap color_map;
        auto it = color_map.map_.find(key);
        if (color_map.map_.end() == it)
        {
            return UNKNOWN;
        }
        return it->second;
    }
private:
    ColorMap()
    {
        map_["未识别"] = UNKNOWN;
        map_["黑"] = BLACK;
        map_["蓝"] = BLUE;
        ...
    }
private:
    std::map map_;
}

使用起来就是简单的一句: int color = ColorMap::Get("蓝");
使用表驱动法,当映射项目有变化的时候,只需要修改map_初始化的地方即可,也就是一行代码的事情,其他地方不需要动。
使用策略模式,呵呵,首先你需要修改子类(子策略),可能是增加,可能是减少,也可能是变动;然后你还要修改从key到value之间的映射代码(怎么映射,看你怎么实现了,手法很多),这样你相当于做了很多本来可以省去的工作。
实际上这个问题的焦点本来就应该只是“映射关系”,也就是map_初始化的那段代码而已。使用表驱动法可以直入问题要害,一针见血。扩展性也不输策略模式。

这里我并不是反对设计模式,而是要提醒在使用模式的时候,一定要注意使用场景。LZ如果细心的话,应该已经注意到我举的例子里头实际上已经包含了一个很有名的模式 ^_^

嗯,多谢了,后来我也将类改了,使用了数组来替代map,同时也传入一个转换的初始值.这样不管字典添加多少,都不用修改类,只要在创建对象的时候使用不同的字典数组初始化对象就可以。。
这样就少写了很多代码,有时候在扩展性和简化代码之间,很难取舍,耦合的概念也是一塌糊涂。。高手推荐本书看看吧,呵呵,谢谢了,稍后晚些结题给分。

#22


简化代码不一定会降低扩展性,两者不是非黑即白的关系。实际上很多具备扩展性的设计都是很简洁的代码,举个例子,《Modern C++ Design》里头有个著名的Typelist,只有简简单单的5行代码,但却是我目前为止见过的最精巧的5行代码,没有之一。通过它,可以非常省力且优雅地设计出函数对象(Functor,很多设计模式都使用了这个东西,比如Command,参见loki库源码)。

一般学习设计模式都有三个阶段:
1. 只有概念,没有实际经验(一般只有程序上规模了,才需要考虑结构的优化,才需要考虑引入设计模式,对几百行的代码用各种模式其实是很eggache的行为。。。)
2. 入门了,尝试在各种项目中使用(比如重构以往的代码),但往往不得要领,误用模式,把原本简单的设计复杂化(我就经历过这个阶段,现在看看当时写的代码,哎,只能对那个时候的自己说:呵呵。。。)
3. 渐渐领悟到要领,不再误用模式, 不再陷入那种叠床架屋的设计陷阱

学习设计模式最重要的,其实是清楚地知道, 什么时候不要用模式,而不是什么时候用模式。因为很多模式是通过增加间接层来实现解耦或者扩展的目的,这样做有好有坏。坏处是增加设计的复杂度,有时候往往划不来。

设计模式针对的是程序结构的优化,只有你的程序上了规模了,必须进行结构优化了,才需要考虑引入模式。否则往往是过度设计。当然,如果仅仅是学习之用,就不必这么拘谨,随便用;但在正式项目中使用,一定要看清场合。

耦合的概念,比较典型的例子就是模型和视图的解耦,这个可以参考《Head First设计模式》里头那个著名的MVC模式的例子。

LZ可以看看《重构》那本书。设计模式通过重构代码来学习是最容易入门的。但要想弄清楚模式里头的坑,那需要大量的项目经验,大量的编码经验,不是仅仅靠看书能学会的。一句话:程序是一行一行写出来的,熟能生巧。

PS: 如果LZ使用的语言是C++,那么可以尝试使用模板来进行设计(泛型编程)。模板的威力是巨大的,不亚于GOF设计模式。推荐《Modern C++ Design》,里头有很多你闻所未闻的设计。记得我第一次看完这本书之后,只有一个感觉:我原来对模板一无所知。。。

引用 21 楼 xiaoxiaoyu85 的回复:
Quote: 引用 20 楼 yao050421103 的回复:

对于LZ的问题,map已经足够,不需要硬套设计模式。否则就本末倒置了。
很多比较有用的设计模式关注的是模块之间的解耦,比如Observer。至于动态的行为替换,见仁见智,策略模式不一定就完美,表驱动法也不一定坏。
直接上代码吧,LZ可以参考:

struct ColorMap
{
public:
    static int Get(const std::string& key)
    {
        static ColorMap color_map;
        auto it = color_map.map_.find(key);
        if (color_map.map_.end() == it)
        {
            return UNKNOWN;
        }
        return it->second;
    }
private:
    ColorMap()
    {
        map_["未识别"] = UNKNOWN;
        map_["黑"] = BLACK;
        map_["蓝"] = BLUE;
        ...
    }
private:
    std::map map_;
}

使用起来就是简单的一句: int color = ColorMap::Get("蓝");
使用表驱动法,当映射项目有变化的时候,只需要修改map_初始化的地方即可,也就是一行代码的事情,其他地方不需要动。
使用策略模式,呵呵,首先你需要修改子类(子策略),可能是增加,可能是减少,也可能是变动;然后你还要修改从key到value之间的映射代码(怎么映射,看你怎么实现了,手法很多),这样你相当于做了很多本来可以省去的工作。
实际上这个问题的焦点本来就应该只是“映射关系”,也就是map_初始化的那段代码而已。使用表驱动法可以直入问题要害,一针见血。扩展性也不输策略模式。

这里我并不是反对设计模式,而是要提醒在使用模式的时候,一定要注意使用场景。LZ如果细心的话,应该已经注意到我举的例子里头实际上已经包含了一个很有名的模式 ^_^

嗯,多谢了,后来我也将类改了,使用了数组来替代map,同时也传入一个转换的初始值.这样不管字典添加多少,都不用修改类,只要在创建对象的时候使用不同的字典数组初始化对象就可以。。
这样就少写了很多代码,有时候在扩展性和简化代码之间,很难取舍,耦合的概念也是一塌糊涂。。高手推荐本书看看吧,呵呵,谢谢了,稍后晚些结题给分。

#23


引用 22 楼 yao050421103 的回复:
简化代码不一定会降低扩展性,两者不是非黑即白的关系。实际上很多具备扩展性的设计都是很简洁的代码,举个例子,《Modern C++ Design》里头有个著名的Typelist,只有简简单单的5行代码,但却是我目前为止见过的最精巧的5行代码,没有之一。通过它,可以非常省力且优雅地设计出函数对象(Functor,很多设计模式都使用了这个东西,比如Command,参见loki库源码)。

一般学习设计模式都有三个阶段:
1. 只有概念,没有实际经验(一般只有程序上规模了,才需要考虑结构的优化,才需要考虑引入设计模式,对几百行的代码用各种模式其实是很eggache的行为。。。)
2. 入门了,尝试在各种项目中使用(比如重构以往的代码),但往往不得要领,误用模式,把原本简单的设计复杂化(我就经历过这个阶段,现在看看当时写的代码,哎,只能对那个时候的自己说:呵呵。。。)
3. 渐渐领悟到要领,不再误用模式, 不再陷入那种叠床架屋的设计陷阱

学习设计模式最重要的,其实是清楚地知道, 什么时候不要用模式,而不是什么时候用模式。因为很多模式是通过增加间接层来实现解耦或者扩展的目的,这样做有好有坏。坏处是增加设计的复杂度,有时候往往划不来。

设计模式针对的是程序结构的优化,只有你的程序上了规模了,必须进行结构优化了,才需要考虑引入模式。否则往往是过度设计。当然,如果仅仅是学习之用,就不必这么拘谨,随便用;但在正式项目中使用,一定要看清场合。

耦合的概念,比较典型的例子就是模型和视图的解耦,这个可以参考《Head First设计模式》里头那个著名的MVC模式的例子。

LZ可以看看《重构》那本书。设计模式通过重构代码来学习是最容易入门的。但要想弄清楚模式里头的坑,那需要大量的项目经验,大量的编码经验,不是仅仅靠看书能学会的。一句话:程序是一行一行写出来的,熟能生巧。

PS: 如果LZ使用的语言是C++,那么可以尝试使用模板来进行设计(泛型编程)。模板的威力是巨大的,不亚于GOF设计模式。推荐《Modern C++ Design》,里头有很多你闻所未闻的设计。记得我第一次看完这本书之后,只有一个感觉:我原来对模板一无所知。。。

Quote: 引用 21 楼 xiaoxiaoyu85 的回复:

Quote: 引用 20 楼 yao050421103 的回复:

对于LZ的问题,map已经足够,不需要硬套设计模式。否则就本末倒置了。
很多比较有用的设计模式关注的是模块之间的解耦,比如Observer。至于动态的行为替换,见仁见智,策略模式不一定就完美,表驱动法也不一定坏。
直接上代码吧,LZ可以参考:

struct ColorMap
{
public:
    static int Get(const std::string& key)
    {
        static ColorMap color_map;
        auto it = color_map.map_.find(key);
        if (color_map.map_.end() == it)
        {
            return UNKNOWN;
        }
        return it->second;
    }
private:
    ColorMap()
    {
        map_["未识别"] = UNKNOWN;
        map_["黑"] = BLACK;
        map_["蓝"] = BLUE;
        ...
    }
private:
    std::map map_;
}

使用起来就是简单的一句: int color = ColorMap::Get("蓝");
使用表驱动法,当映射项目有变化的时候,只需要修改map_初始化的地方即可,也就是一行代码的事情,其他地方不需要动。
使用策略模式,呵呵,首先你需要修改子类(子策略),可能是增加,可能是减少,也可能是变动;然后你还要修改从key到value之间的映射代码(怎么映射,看你怎么实现了,手法很多),这样你相当于做了很多本来可以省去的工作。
实际上这个问题的焦点本来就应该只是“映射关系”,也就是map_初始化的那段代码而已。使用表驱动法可以直入问题要害,一针见血。扩展性也不输策略模式。

这里我并不是反对设计模式,而是要提醒在使用模式的时候,一定要注意使用场景。LZ如果细心的话,应该已经注意到我举的例子里头实际上已经包含了一个很有名的模式 ^_^

嗯,多谢了,后来我也将类改了,使用了数组来替代map,同时也传入一个转换的初始值.这样不管字典添加多少,都不用修改类,只要在创建对象的时候使用不同的字典数组初始化对象就可以。。
这样就少写了很多代码,有时候在扩展性和简化代码之间,很难取舍,耦合的概念也是一塌糊涂。。高手推荐本书看看吧,呵呵,谢谢了,稍后晚些结题给分。


嗯,太感谢了,做了几年通讯,大部分都是写C的语句,比较主动性能,对设计模式和OOP真的欠缺很多。模板的重要性也是最近才意识到,立即去看,

推荐阅读
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • flowable工作流 流程变量_信也科技工作流平台的技术实践
    1背景随着公司业务发展及内部业务流程诉求的增长,目前信息化系统不能够很好满足期望,主要体现如下:目前OA流程引擎无法满足企业特定业务流程需求,且移动端体 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • 本文讨论了Alink回归预测的不完善问题,指出目前主要针对Python做案例,对其他语言支持不足。同时介绍了pom.xml文件的基本结构和使用方法,以及Maven的相关知识。最后,对Alink回归预测的未来发展提出了期待。 ... [详细]
  • 本文介绍了如何找到并终止在8080端口上运行的进程的方法,通过使用终端命令lsof -i :8080可以获取在该端口上运行的所有进程的输出,并使用kill命令终止指定进程的运行。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • http:my.oschina.netleejun2005blog136820刚看到群里又有同学在说HTTP协议下的Get请求参数长度是有大小限制的,最大不能超过XX ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • Linux如何安装Mongodb的详细步骤和注意事项
    本文介绍了Linux如何安装Mongodb的详细步骤和注意事项,同时介绍了Mongodb的特点和优势。Mongodb是一个开源的数据库,适用于各种规模的企业和各类应用程序。它具有灵活的数据模式和高性能的数据读写操作,能够提高企业的敏捷性和可扩展性。文章还提供了Mongodb的下载安装包地址。 ... [详细]
  • 本文介绍了Linux Shell中括号和整数扩展的使用方法,包括命令组、命令替换、初始化数组以及算术表达式和逻辑判断的相关内容。括号中的命令将会在新开的子shell中顺序执行,括号中的变量不能被脚本余下的部分使用。命令替换可以用于将命令的标准输出作为另一个命令的输入。括号中的运算符和表达式符合C语言运算规则,可以用在整数扩展中进行算术计算和逻辑判断。 ... [详细]
  • 本文介绍了在Windows系统上使用C语言命令行参数启动程序并传递参数的方法,包括接收参数程序的代码和bat文件的编写方法,同时给出了程序运行的结果。 ... [详细]
  • iOS超签签名服务器搭建及其优劣势
    本文介绍了搭建iOS超签签名服务器的原因和优势,包括不掉签、用户可以直接安装不需要信任、体验好等。同时也提到了超签的劣势,即一个证书只能安装100个,成本较高。文章还详细介绍了超签的实现原理,包括用户请求服务器安装mobileconfig文件、服务器调用苹果接口添加udid等步骤。最后,还提到了生成mobileconfig文件和导出AppleWorldwideDeveloperRelationsCertificationAuthority证书的方法。 ... [详细]
author-avatar
平凡快乐的girl_819
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有