java 设计模式之简单化工厂和策略者模式

一 简单工厂

刚开始学习java的时候,老师布置一项作业就是写一个简单的计算器,功能很简单就是加减乘除,下完课以后不要半小时就搞完了 然后就打游戏去了,代码大概是这样的:

double result=0d;
Scanner sc = new Scanner(System.in);   
System.out.println("输入第一个numberA值:");  
numberA= sc.nextDouble();
System.out.println("输入第二个numberB值:");  
numberB= sc.nextDouble();
System.out.println("输入第运算符:");  
String type= sc.next();
switch(type){
  case "+":
  result=numberA+numberB;
   break;
  case "-":
  result= numberA-numberB;
   break;
  case "*":
  result= numberA-numberB;
   break;
  case "/":
  result= numberA/numberB;
   break;   
}
 
System.out.println( result);

}

         作业交上去以后以为任务完成了,到了下次上课的时候,老师说你们的作业都很有特点啊,都是基本上一样的,没有我想看到的东西,然后他接着说,这个东西确实简单,但是你们考虑的是如何实现它,你们忘记了我们这么语言的吸引人的地方,举个例子假设我要加一个求平方和运算,但是这个东西正在被人使用,难道你们要去跟人家说现在暂时先别使用这个功能,假设这是一个商场里面的计算器怎么办?假设这个代码放在不同的地方使用,人家可能不想使用平方和,人家要还要开根运算怎么办? 怎么才能写出易维护,可复用,灵活性高的代码?在后面 我会把我学习的东西慢慢都写进来,完全是我自己的观点,不喜勿喷!!!!

     真正的大牛写出来的代码是优美的。而我们作为菜鸟 也只能慢慢在学习路途中结伴而行。好了说这么多该说正事了!

     对于上面说的这些情况 我们完全可以考虑把逻辑分开,加减乘除看做不同的类,每次使用加减乘除,都去具体实例化对应的对象,这样是不是就分开了 

public class Operate{

    public static double numberA;
    public  static double numberB;
 public double getResult(){
double result=0d;

return result;
}
 public class Add  extends Operate{
 public double getResult(){
double result=numberA+numberB;
return result;
}
 }
 public class Sub  extends Operate{
 public double getResult(){
double result=numberA-numberB;
return result;
}
 }
 public class mul  extends Operate{
 public double getResult(){
double result=numberA*numberB;
return result;
}
 }
 public class div  extends Operate{
 public double getResult(){
double result=numberA/numberB;
return result;
}
 }

}

假设我们加一个开根是不是只需要加一个类就行了,当然我们不应该以这种写内部类的方式,我这里是为了简便,这样是不是很符合 开放-封闭原则,但是我们每次都去new 是不是很麻烦,我们可以创建一个类去帮我们实例化对象,这个类就可以看做一个工厂

public class FactoryCreateOperate{
 public  Operate createOperate(String type){
 Operate o=new Operate();
switch(type){
  case "+":
  o=new Operate().new Add();//因为我是直接把这些加减乘除写在Operate 内部类里面 ,所以要这样 实例化
   break;
  case "-":
  o=new Operate().new Sub();
   break;
  case "*":
  o=new Operate().new Mul();
   break;
  case "/":
  o=new Operate().new Div();
   break;   
}
 return o;
 }

}

客户端功能 只需要

 Operate o=new FactoryCreateOperate().createOperate(type);
double result= o.getResult();

System.out.println( result);

二策略者模式

   对于这个计算器代码我们也可以换成另外一种思想,我们可以把每一种算法看成一种决策方式,假设调用加法运算,就是加法运算策略,我们可以用一个配置文件来实现  逻辑分类不变,

public class Operate{

    public static double numberA;
    public  static double numberB;
 public double getResult(){
double result=0d;

return result;
}
 public class Add  extends Operate{
 public double getResult(){
double result=numberA+numberB;
return result;
}
 }
 public class Sub  extends Operate{
 public double getResult(){
double result=numberA-numberB;
return result;
}
 }
 public class Mul  extends Operate{
 public double getResult(){
double result=numberA*numberB;
return result;
}
 }
 public class Div  extends Operate{
 public double getResult(){
double result=numberA/numberB;
return result;
}
 }

Contex配置文件如下

public class Contex{


public Operate op=null;

public Contex(Operate op){
this.op=op;
}
public Double getResult(){
return op.getResult();
}
}

 客户端文件 如下

switch(type){
  case "+":
  con=new Contex(new Operate().new Add());
   break;
  case "-":
  con=new Contex(new Operate().new Sub());
   break;
  case "*":
  con=new Contex(new Operate().new Mul());
   break;
  case "/":
  con=new Contex(new Operate().new Div());
   break;   

}

可能大家会觉得 客户端还是有 switch  感觉跟最原始的代码没啥区别,这也简单 我们可以使用简单工厂和策略者模式结合,

Contex文件做如下修改



public class Contex{


public Operate op=null;

public Contex(String type){
switch(type){
  case "+":
  op=new Operate().new Add();
   break;
  case "-":
  op=new Operate().new Sub();
   break;
  case "*":
  op=new Operate().new Mul();
   break;
  case "/":
  op=new Operate().new Div();
   break;   
}
}
public Double getResult(){
return op.getResult();
}

}

客户端 就非常简洁了

Contex con=new Contex(type); 
System.out.println(con.getResult());

new FactoryCreateOperate().createOperate(type);

有没有发现其实 简单化工厂模式需要认识的是两个对象

Operate o=new FactoryCreateOperate().createOperate(type); 一个是Operate 一个是FactoryCreateOperate

而策略者和简单工厂结合只需要认识一个类contex,简单化工厂和策略者模式是两个思想,大家以为到这里就结束了其实这个代码还可以优化,contex 里面switch,如果我有需要加很多功能 难道要在swtich 后面追加吗?提示大家可以通过java 反射机制来做!

猜你喜欢

转载自blog.csdn.net/l_mr_l/article/details/80505906