- 1. 简单工厂模式
- 1.1 内容
- 1.2 优缺点
- 2. 策略模式
- 2.1 内容
- 2.2 优点
- 3. 工厂模式
- 3.1 内容
- 4. 工厂模式和策略模式的关系
这么大岁数了才开始研究设计模式,而且一直没有理解。
现在明白了,虽然我能看懂代码,但是感觉并没有领会其中的意思,主要的思想就是目前的需求能不能用这个模式,如果用,要怎么写。
1. 简单工厂模式 1.1 内容
有一堆有相同类型的类,它们叫做产品类,把它们的公共部分抽象出来,这样就生成了一个产品抽象类,这个类都是虚函数,具体的内容由子类实现。
另有一个工厂类,每个类都由工厂类负责实例化,我选择在工厂类的析构中删掉这个类。
将一堆类抽象出来基类是个很基本的 *** 作,简单工厂模式的核心在于这个工厂,即这些产品类要怎么实例化,简单工厂模式用一个工厂类进行实例化。
下面的代码是我自己写的,有三款手机,诺基亚、小米和谷歌,基类自然就是手机类,工厂类根据输入的类型决定生产什么产品。
#include
class mobile
{
public:
mobile() = default;
virtual void brand(void) = 0;
virtual ~mobile() = default;
};
class nokia : public mobile
{
public:
void brand(void)
{
std::cout<<"nokia"<brand();
delete(nn);
mobile* nnokia = Factory.create_project(Nokia);
nnokia->brand();
delete(nnokia);
return 0;
}
客观问题来的时候,将可变的东西变成产品类。
例如要做一个软件系统,支持给货物打折,后续也可能支持返利,或者其它优惠活动,这种情况肯定就是把返利、打折做成产品子类,产品抽象类就是付款。
上面的方法delete为什么没放在析构里呢?因为放了就成了工厂和策略的集合,具体的看下面。
特点:工厂类封装了创建具体产品对象的函数。
缺点:扩展性差,新增产品的时候需要修改工厂类。
例如再加一个一加,就要在工厂类中增加一个case。
没太看明白策略,只看懂了策略+工厂。
和简单工厂一样,都是先在待扩展的内容中找到公共部分,抽象出父类,简单工厂中叫做产品抽象类,策略模式中叫算法类,也都没差。
更有意思的是,工厂类和上下文类又很像不是吗?都是在类内new一下,只不过简单工厂不存数据,直接把new出来的结果返回,策略+工厂替你保存结果。
策略+工厂和工厂的区别不仅仅是是否保存,简单工厂的话,使用者需要了解工厂类和抽象产品,因为用的是具体产品类接收的工厂类返回值。
然而策略+工厂根本不需要知道产品相关的任何类,因为都被封装在了上下文类的内部,调用什么函数context会替你做的,这样降低了耦合。
#include
class strategy
{
public:
strategy(void) = default;
virtual ~strategy() = default;
virtual double get_money(double) = 0;
};
class account : public strategy
{
public:
account(void) = default;
virtual ~account() = default;
double get_money(double get)
{
return get*0.8;
}
};
class all : public strategy
{
public:
all(void) = default;
virtual ~all() = default;
double get_money(double get)
{
return get;
}
};
class full_min : public strategy ///<不知道满减怎么说,瞎写吧
{
public:
full_min(void) = default;
virtual ~full_min() = default;
double get_money(double get)
{
return get>500 ? get-100 : get;
}
};
enum details
{
enum_account,
enum_all,
enum_full_min,
};
class Context
{
public:
strategy* cs;
Context(const enum details &ss)
{
switch (ss)
{
case enum_account:
cs = new account;
break;
case enum_all:
cs = new all;
break;
case enum_full_min:
cs = new full_min;
break;
default:
cs = nullptr;
break;
}
}
virtual ~Context()
{
if(nullptr!=cs)
delete(cs);
}
double get_result(double input)
{
return cs!=nullptr ? cs->get_money(input) : 0;
}
};
int main(void)
{
Context context(enum_account);
std::cout<
2.2 优点
优点:
算法可以自由切换;
避免使用多重条件判断(如果不用策略模式我们可能会使用多重条件语句,不利于维护);
扩展性良好,增加一个策略只需实现接口即可。
缺点:
策略类数量会增多,每个策略都是一个类,复用的可能性很小;
所有的策略类都需要对外暴露。
简单工厂确实简单,但是如果新加一个运算的话就要去工厂中修改内容,也就违背了开放封闭原则(只加内容而不改代码)。
那是不是可以把工厂的那个case也抽象出来,这样每次增加需求就只增加类就可以了,不需要修改代码。
按照我的理解:switch-case是开放封闭原则的死敌
按照我的写法就是用抽象类替代需要修改的switch-case,这样没有太大的修改时就不需要动facotry类,只需要增加新的子工厂类就OK了。
话虽如此,但是工厂类的delete *** 作还是在外面完成的,和策略+工厂的方式比还差一些。
#include
class mobile
{
public:
mobile() = default;
virtual void brand(void) = 0;
virtual ~mobile() = default;
};
class nokia : public mobile
{
public:
void brand(void)
{
std::cout<<"nokia"<brand();
delete(mobilephone);
return 0;
}
下面是策略+工厂的写法,不过这里命名有点问题,肯定不应该叫做工厂,而且用工厂的思路来处理,工厂怎么能负责维护产品呢?他们只负责造,造出来就不管了。
所以工厂类的名字应该还是上下文,有一堆上下文,而这上下文策略子类确实是负责维护“产品”信息,所有对产品的 *** 作都通过对上下文的调用。
还是那句话,如果把上下文称为工厂必然就不合适了。
class factory
{
public:
factory() = default;
virtual ~factory() = default;
};
class google_factory : public factory
{
public:
google_factory(void)
{
p_project = new google;
}
virtual ~google_factory()
{
delete(p_project);
return;
}
void get_brand(void)
{
p_project->brand();
}
private:
mobile* p_project;
};
int main(void)
{
google_factory gf;
gf.get_brand();
return 0;
}
4. 工厂模式和策略模式的关系
就跟我之前想的是一样的,既然你要生产东西,工厂模式会把你想要的东西给你,要怎么用是你的事,因此用户也要会用产品才行,需要了解实际产品类和工厂类。
策略模式是不允许直接 *** 作子策略的,会由上下文包装后才行,所以你只要了解上下文类(对应工厂模式的工厂类)就可以了。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)