简单⼯⼚模式
在⽇常开发中,凡是需要⽣成复杂对象的地⽅,都可以尝试考虑使⽤⼯⼚模式来代替。
复杂对象指的是类的构造函数参数过多等对类的构造有影响的情况,因为类的构造过于复杂,如果直接在其他业务类内使⽤,则两者
的耦合过重,后续业务更改,就需要在任何引⽤该类的源代码内进⾏更改,光是查找所有依赖就很消耗时间了,更别说要⼀个⼀个修
改了。
⼯⼚模式的定义:
是指定义⼀个创建产品对象的⼯⼚接⼝,将产品对象的实际创建⼯作推迟到具体⼦⼯⼚类当中。这满⾜创建型模式中所要求的“创建与
使⽤相分离”的特点。
按实际业务场景划分,⼯⼚模式有3种不同的实现⽅式,分别是
简单⼯⼚模式
⼯⼚⽅法模式
抽象⼯⼚模式
⼀、简单⼯⼚模式
1、简单⼯⼚模式的定义
简单⼯⼚模式(SimpleFactoryPattern),⼜叫作静态⼯⼚⽅法模式(StaticFactoryMethodPattern)。
我们把被创建的对象称为“产品”,把创建产品的对象称为“⼯⼚”。如果要创建的产品不多,只要⼀个⼯⼚类就可以完成,这种模
式叫“简单⼯⼚模式”。
简单来说,简单⼯⼚模式有⼀个具体的⼯⼚类,可以⽣成多个不同的产品,属于创建型设计模式。
简单⼯⼚模式不在GoF23种设计模式之列。
2、简单⼯⼚模式的结构
(1)简单⼯⼚模式主要3个⾓⾊
简单⼯⼚(SimpleFactory):
是简单⼯⼚模式的核⼼,负责实现创建所有实例的内部逻辑。⼯⼚类的-建产品类的⽅法可以被外界直接调⽤,创建所需的产品对象。
抽象产品(Product):
是简单⼯⼚创建的所有对象的⽗类,负责描述所有实例共有的公共接⼝。
具体产品(ConcreteProduct):
-是简单⼯⼚模式的创建⽬标。
(2)结构图如下:(图来⾃⽹络)
3、优缺点
主要优点:
结构简单,调⽤⽅便。⼯⼚和产品的职责区分明确。
客户端⽆需知道所创建具体产品的类名,只需知道参数即可。
主要缺点:
简单⼯⼚模式的⼯⼚类单⼀,负责所有产品的创建,职责过重,⼀旦异常,整个系统将受影响。且⼯⼚类代码会⾮常臃肿,违背⾼聚合
原则。
4、使⽤场景
对于产品种类相对较少的情况,考虑使⽤简单⼯⼚模式。使⽤简单⼯⼚模式的客户端只需要传⼊⼯⼚类的参数,不需要关⼼如何创建对象的
逻辑,可以很⽅便地创建所需产品。
5、在框架源码中使⽤也很⼴泛
JDK源码中的tance()⽅法
Logback源码中多个重载的getLogger()⽅法
⼆、模式的通⽤实现
代码如下:
publicclassSimpleFactoryPattern{
publicstaticvoidmain(String[]args){
Productproduct=oduct(2);
();
}
//抽象产品
publicinterfaceProduct{
voidshow();
}
//具体产品:ProductA
staticclassConcreteProduct1implementsProduct{
@Override
publicvoidshow(){
n("具体产品1显⽰...");
}
}
//具体产品:ProductB
staticclassConcreteProduct2implementsProduct{
@Override
publicvoidshow(){
n("具体产品2显⽰...");
}
}
//具体产品:ProductC
staticclassConcreteProduct3implementsProduct{
@Override
publicvoidshow(){
n("具体产品3显⽰...");
}
}
finalclassConst{
staticfinalintPRODUCT_A=0;
staticfinalintPRODUCT_B=1;
staticfinalintPRODUCT_C=2;
}
staticclassSimpleFactory{
publicstaticProductmakeProduct(intkind){
switch(kind){
T_A:
returnnewConcreteProduct1();
T_B:
returnnewConcreteProduct2();
T_C:
returnnewConcreteProduct3();
}
returnnull;
}
}
}
三、模式的应⽤实例
简易计算器为例,需求:输⼊两个数和运算符,得到结果。
1、抽象产品
publicabstractclassOperation{
protectedabstractdoublecompute(doublenumber1,doublenumber2)throwsException;
}
2、具体产品
加法
publicclassOperationAddextendsOperation{
@Override
protecteddoublecompute(doublenumber1,doublenumber2){
returnnumber1+number2;
}
}
减法
publicclassOperationSubextendsOperation{
@Override
protecteddoublecompute(doublenumber1,doublenumber2){
returnnumber1-number2;
}
}
乘法
publicclassOperationMulextendsOperation{
@Override
protecteddoublecompute(doublenumber1,doublenumber2){
returnnumber1*number2;
}
}
除法
publicclassOperationDivextendsOperation{
@Override
protecteddoublecompute(doublenumber1,doublenumber2)throwsException{
if(number2==0){
thrownewException("除数不能为0!");
}
returnnumber1/number2;
}
}
3、简单⼯⼚
这⾥对简单⼯⼚创建产品进⾏了优化。可以通过缓存、配置⽂件、反射和泛型等技术了优化。
如果运算业务需要扩展,需要创建具体运算类即可,不需要再修改简单⼯⼚类了。
publicclassOperationFactory{
privatestaticfinalMap
static{
("+",newOperationAdd());
("-",newOperationSub());
("*",newOperationMul());
("/",newOperationDiv());
}
publicstaticOperationcreateOperate0(Stringoperate){
if(operate==null||y()){
returnnull;//返回null还是IllegalArgumentException全凭你⾃⼰说了算
}
(operate);
}
/**
*createOperate0运⽤缓存技术,节省内存和对象创建的时间
*createOperate0和createOperate1同理
*/
*/
publicstaticOperationcreateOperate1(Stringoperate){
Operationoperation=null;
switch(operate){
ca"+":
operation=newOperationAdd();break;
ca"-":
operation=newOperationSub();break;
ca"*":
operation=newOperationMul();break;
ca"/":
operation=newOperationDiv();break;
}
returnoperation;
}
/**
*createOperate1⽅法不符合开闭原则
*如果运算业务继续扩展,需要创建具体运算类,也需要修改简单⼯⼚的createOperate1⽅法。
*采⽤反射技术进⾏优化,即createOperate2⽅法
*/
publicstaticOperationcreateOperate2(StringclassName){
Operationoperation=null;
try{
if(!(null==className||"".equals(className))){
operation=(Operation)e(className).newInstance();
}
}catch(Exceptione){
tackTrace();
}
returnoperation;
}
/**
*createOperate2⽅法中类型强制转型,参数为字符串,可控性不⾼
*采⽤反射和泛型技术进⾏优化,即createOperate3⽅法
*/
publicstaticOperationcreateOperate3(Class<?extendsOperation>clazz){
try{
if(null!=clazz){
tance();
}
}catch(Exceptione){
tackTrace();
}
returnnull;
}
}
4、测试
publicclassTest{
publicstaticvoidmain(String[]args)throwsException{
doublenum1=10;
doublenum2=2;
n(Operate0("*").compute(num1,num2));
n(Operate1("*").compute(num1,num2));
Operationoperate2=Operate2("ionDiv");
n(e(num1,num2));
Operationoperate3=Operate3();
n(e(num1,num2));
}
}
参考⽂章:
设计模式:
——olish.求知若饥,虚⼼若愚。
本文发布于:2023-01-03 12:17:22,感谢您对本站的认可!
本文链接:http://www.wtabcd.cn/fanwen/fan/90/84373.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |