不知道有没有同我一样的人,对于某些概念性的东西本身就不重视, 总是认为编程语言我会就好了,干嘛还去记概念,
难道就为了面试吗?
看着跟自己技术水平差不多的人拿着比自己高一倍的薪资,你是不是也很不服气, 其实如果你不那么固执,也许你工作四年才领悟到的事情,其实,你两年前就该清楚了。我只举个简单的例子吧,以免像我这样固执的人继续固执下去,及时回头吧。
以前没工作的时候老师是这样说的,对于这些技术啊、概念啊,不用死记硬背, 你以后工作了用的多了自然就熟悉了。对于这样的话自己也是深信不疑,可当自己面试的时候别人总会让你说出东西来,你跟别人说,我知道该怎么去做,但我需要上网搜索下具体调用的函数才行, 这样别人不会接受你,因为“口说无凭”。 像面试的时候,给你一道分离字符串的题, 你可能知道使用C语言的函数strtok,但是就是对于它的传参记不清了, 又或者你想用C++的string类型的find/substr结合起来,但也是记不清了,甚至find的返回类型std::string::npos你都记不清楚了, 这样面试官会怎么想, 肯定会觉得你不行。
你也总认为,为什么以前没我技术好的人,为什么轻易拿到了高工资。 我也有这样的疑惑, 可你是不是和我一样清楚自己,其实自己会的东西很少,想写个类需要百度或者Google才行。 你觉得这样的你,面试官为什么要给你高薪offer呢?
所以,请早一点意识到自己的不足,充实自己。 问一句,你看过什么技术书籍? 我是做C/C++的,但是我连一本完整的书籍都没有看完过, 所以这就是你的软肋。
该看什么书籍,作为技术人员就要自己去调查,不要总等着别人给你推荐,或者等着工作需要的时候再去看。 所以我说,如果你早点意识到这一点, 你也许只用1年就可以20k了。
为什么有的人本科毕业就高薪,有的人工作四五年还是一般,因为你懂得知识多少,跟你工作年限无关,跟你自己肚子里有多少“货”有关。
前面都是一些个人感慨,希望不要像我这样失败吧。
因为我个人喜欢一篇文章把事情说完,所以我就只写一个标题,我慢慢更新不同的模式。
想学习这些模式的可以看菜鸟教程( http://www.runoob.com/design-pattern/abstract-factory-pattern.html )
下面如果我解释概念的话,肯定都是按照我自己的理解说,有不对的地方请海涵吧, 因为我真的很菜。(如果我自己更新的时候发现不对也会改正的)
1. 工厂模式
个人理解: 当你想用一个类的接口来完成对不同对象的实例创建的时候,可以考虑用工厂模式。 就像现实中的工厂一样,工厂里面可以生产很多不同的东西。下面写一个例子, 制造不同的形状,像圆形、矩形、正方形, 如果我们不用工厂模式,那我们写好三个类之后,每次使用的时候就直接构造相应的对象, 例如,在main函数里面写代码 new Circle, new Rectangle, new Square 。 如果我们使用工厂模式,那我们用factory的一个接口去创建不同的实例,然后返回就好了。sample里面我用了智能指针,如果不用智能指针的话就很容易内存泄漏,要防止内存泄漏,你自己写就麻烦一点,而智能指针很方便。
代码如下:
#include <iostream>
#include <stdio.h>
#include <string>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <memory>
using namespace std;
using SHAPETYPE = enum {
INVALID,
CIRCLE,
RECTANGLE,
SQUARE
};
using Shape = class Shape {
public:
Shape() = default;
virtual ~Shape() {
std::cout<<__func__<<std::endl;
}
virtual void draw() {
std::cout<<"Shape::draw()"<<std::endl;
}
};
using Circle = class Circle: public Shape {
public:
Circle() = default;
~Circle() {
std::cout<<__func__<<std::endl;
}
void draw() {
std::cout<<"Circle::draw()"<<std::endl;
}
};
using Rectangle = class Rectangle: public Shape{
public:
Rectangle() = default;
~Rectangle() {
std::cout<<__func__<<std::endl;
}
void draw() {
std::cout<<"Rectangle::draw()"<<std::endl;
}
};
using Square = class Square : public Shape{
public:
Square() = default;
~Square() {
std::cout<<__func__<<std::endl;
}
void draw() {
std::cout<<"Square::draw()"<<std::endl;
}
};
using Factory = class Factory {
public:
Factory() = default;
~Factory() {
std::cout<<__func__<<std::endl;
}
shared_ptr<Shape> getShape(SHAPETYPE type) {
switch(type) {
case CIRCLE:
return shape_ = make_shared<Circle>();
case RECTANGLE:
return shape_ = make_shared<Rectangle>();
case SQUARE:
return shape_ = make_shared<Square>();
case INVALID:
default:
shape_ = nullptr; // 这里把shape_设置为nullptr,则上个对象的智能指针计数器会减少1
return shape_;}
}
private:
shared_ptr<Shape> shape_;
};
int main(int argc, char** argv) {
auto factory = make_shared<Factory>();
factory->getShape(CIRCLE)->draw();
factory->getShape(RECTANGLE)->draw();
factory->getShape(SQUARE)->draw();
factory->getShape(INVALID); // 这个的话最后一个对象的智能指针计数器减为0,释放对象
return EXIT_SUCCESS;
}
对于需要的类还是按以前那种写法, 只是多了一个Factory类, 而这个类就是为了生成不同的对象实例而创造的。
也许你用过这样的东西,只是不知道它有名字,就叫做“工厂模式”,如果你用过那就记住它的名字,以后别人和你说的时候你也知道别人说的是什么,如果你没用过,那你就要学习了。
2. 单例模式
下一个再说抽象工厂模式,因为把工厂模式加上单例模式一起使用更好, 而抽象工厂模式可以看做是把工厂模式又抽象了一层。因为抽象工厂模式可以采用多个工厂模式+单例模式,可能我说的就比较难懂吧,毕竟表达能力弱,每次面试也是表达不清,导致失败告终,已习以为常。
只要把上面的代码稍加修改就可以了, 下面我加粗线,这样可以看出改了什么代码。
#include <iostream>
#include <stdio.h>
#include <string>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <memory>
using namespace std;
using SHAPETYPE = enum {
INVALID,
CIRCLE,
RECTANGLE,
SQUARE
};
using Shape = class Shape {
public:
Shape() = default;
virtual ~Shape() {
std::cout<<__func__<<std::endl;
}
virtual void draw() {
std::cout<<"Shape::draw()"<<std::endl;
}
};
using Circle = class Circle: public Shape {
public:
Circle() = default;
~Circle() {
std::cout<<__func__<<std::endl;
}
void draw() {
std::cout<<"Circle::draw()"<<std::endl;
}
};
using Rectangle = class Rectangle: public Shape{
public:
Rectangle() = default;
~Rectangle() {
std::cout<<__func__<<std::endl;
}
void draw() {
std::cout<<"Rectangle::draw()"<<std::endl;
}
};
using Square = class Square : public Shape{
public:
Square() = default;
~Square() {
std::cout<<__func__<<std::endl;
}
void draw() {
std::cout<<"Square::draw()"<<std::endl;
}
};
using Factory = class Factory {
public:
~Factory() {
std::cout<<__func__<<std::endl;
}
// 获取Factory实例的公共接口
static Factory* getInstance() {
return instance_;
}
switch(type) {
case CIRCLE:
return shape_ = make_shared<Circle>();
case RECTANGLE:
return shape_ = make_shared<Rectangle>();
case SQUARE:
return shape_ = make_shared<Square>();
case INVALID:
default:
shape_ = nullptr; // 这里把shape_设置为nullptr,则上个对象的智能指针计数器会减少1
return shape_;}
}
private:
Factory() = default; // 私有化后,不让外部使用构造函数
private:
static Factory* instance_ ; // 用于静态存储Factory实例
shared_ptr<Shape> shape_;};
// 懒汉模式 , 初始化Factory实例, 这样内存中就只有一份,
// 防止了多线程同时获取实例导致的问题
Factory* Factory::instance_ = new Factory();
int main(int argc, char** argv) {
auto factory = Factory::getInstance();
factory->getShape(CIRCLE)->draw();
factory->getShape(RECTANGLE)->draw();
factory->getShape(SQUARE)->draw();
factory->getShape(INVALID); // 这个的话最后一个对象的智能指针计数器减为0,释放对象
return EXIT_SUCCESS;
}