https://blog.csdn.net/Architect_chaser/article/details/106043586
第1章 简单工厂模式
1.1面试受挫
小菜今年计算机专业大四了,学了不少软件开发方面的东西,也学着编了写小程序,踌躇满志,一心想找一个好单位。当投递了无数份简历以后,终于收到了一个单位的面试通知,小菜欣喜若狂。
到了人家单位,前台小姐给了他一份题目,上面写着“请用Java”来实现一个计算器控制程序,要求输入两个数和运算符号,得到结果。
小菜一看,这还不简单,三下五除二,10分钟不到就写完了,小菜写完了,感觉没有什么错误,就交了。交了以后,单位说一周以内等通知吧。于是小菜只能耐心等待,可是半个月过去了,什么消息也没有。小菜很纳闷,我的代码实现了呀,为什么不给我机会呢?
于是小菜找到了从事软件开发7年的大表哥大鸟,请教原因,大鸟问了题目和了解小菜的代码细节以后,说到:小菜啊小菜,你真是菜!!人家单位出题的意思,你都没有明白,当然不会联系你了!
小菜说:我的代码有错吗?单位题目不就是要我实现一个计算器的代码吗?我这样写有什么问题?
class Program{
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
System.out.printl("请输入数字A:");
double A=sc.nextDouble();
System.out.printl("请输入运算符(+ - * /):");
char C=sc.nextChar();
System.out.printl("请输入数字B:");
double B=sc.nextDouble();
double D;
if(C=='+'){
D=A+B;
}else if(C=='-'){
D=A-B;
}else if(C=='*'){
D=A*B;
}else if(C=='/'){
D=A/B;
}else{
System.out.println("你输入的字符非法!");
}
System.out.println("结果是:"+D);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
1.2初学者代码的毛病
大鸟说:“先不说出题人的意思,光是你现在的代码,就有许多不足的地方!"
1.A B C命名很不规范!变量一多,什么A B C D的读起来很恶心!你写的代码不是给你自己读的,是给别人读的!
2.代码鲁棒性太差,我问你,如果第二个操作数是0,你代码不就奔了??
1.3代码规范
偶偶,大表哥你说的很对啊,我现在就改。
大表哥说:小畜生,你的水平还不到家,光是上面两条还不够,我问你,如果这时候,你的老板告诉你,要新加一个开平方的运算,你怎么办?
小菜鸟:这还不简单,多加一个判断不就行了
大表哥:小菜鸡就是菜,新加一个功能如果还要从新编译之前的代码,说明你之前的代码可扩展性太差了,我问你,如果公司让你给一个系统加一个同类功能,难道你还要之前所有功能的源代码吗?笨蛋!如果你在设计的时候就用多态,那不就好了,你先来个Operator抽象类,类里面写个抽象方法,之后如果要加功能,只需要新写这个抽象类的实现类就好了!这样多聪明
小菜鸟:大表哥万岁!!!!!!!!
大表哥:看乖孙子你这么tin话,大表哥今天再教你一招!我问你,多态是有好处,可扩展性大大提高了,但是也带来了问题,这么多对象,我怎么知道什么时候创建那个呢??就算我知道,程序也不知道啊!
1.4简单工厂模式
//Operation.java
public abstract class Operation {
public abstract double getResult(double op1,double op2);
}
- 1
- 2
- 3
- 4
- 5
//OperationAdd.java
public class OperationAdd extends Operation {
@Override
public double getResult(double op1, double op2) {
return op1+op2;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
//OperationDivide.java
public class OperationDivide extends Operation {
@Override
public double getResult(double op1, double op2) {
if(op2==0){
System.out.println("除数不能为0!");
return Double.NEGATIVE_INFINITY;
}
return op1/op2;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
//OperationMultiply.java
public class OperationMultiply extends Operation{
@Override
public double getResult(double op1, double op2) {
return op1*op2;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
//OperationSub.java
public class OperationSub extends Operation {
@Override
public double getResult(double op1, double op2) {
return op1-op2;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
我怎么知道什么时候创建什么那个实现类呢?写个工厂呗
public class OperationFactory {
public static Operation createOperate(char ch){
Operation oper=null;
switch(ch){
case '+':
oper=new OperationAdd();
break;
case '-':
oper=new OperationAdd();
break;
case '*':
oper=new OperationAdd();
break;
case '/':
oper=new OperationAdd();
break;
}
return oper;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
看见了吧,这样你只需要传入一个符号,就可以返回对应的实现类,然后用Operation的父类指针指向他们(多态)然后就可以调用重写的方法啦!
public class Main {
public static void main(String[] args) {
Operation oper=OperationFactory.createOperate('+');
System.out.println(oper.getResult(3,2));
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
1.5总结
大表哥:现在知道了把,小菜鸟,我问你,如果有一天,我们需要更改加法运算,我们只需要改哪里?
小菜鸟:只需要改OperationAdd就可以了
大表哥:那么我们要增加其他的运算,比如平方根,立方根,怎么办?
小菜鸟:只需要怎加相应运算的子类就行了
大表哥:是吗?只有这样?
小菜鸟:欧欧,还要仔工厂类里面的switch中增加分支
大表哥:对啦,那如果要修改界面呢?
小菜鸟:那就去修改界面的类,关运算什么事?
大表哥:你已经学会了多态和简单的工厂模式了
小菜鸟:受我一拜