前言:学习面向对象,不能单单学一些知识点,重要的也要懂点思想,就像学武功一样,基本功当然要扎实,但是同时也要修炼 自己的内功心法,才能让自己越来越强 ,
最近需要学习的知识点
1. UML
2. 面向对象设计原则 (7)
3. 面向对象设计模式(23)
建议: 先将UML学会,然后面向对象设计模式和设计原则(两者一起学习),把常用的设计模式要熟练,其他的也要了解
为什么要学习这些, 原因如果不学习这些东西的话,你永远不知道自己写的代码是否具有可维护性,可扩展性,可复用性 ,灵活性,就不懂的怎么样写出高质量的代码,熟练这些其实对面向对象的理解也会更深一层!
一:简单工厂模式
懒洋洋,沸羊羊,喜洋洋去抖音公司面试,面试官给了一道面试题
使用面向对象的语言,实现一个计算器控制台程序,要求输入两个数和运算符,得到结果
1.1懒洋洋
package 简单工厂模式;
import java.util.Scanner;
public class Demo1{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入第一个数:");
double firstNumber = sc.nextDouble();
sc.nextLine();
System.out.println("请输入运算符:");
String operator = sc.nextLine();
System.out.println("请输入第二个数:");
double secondNumber = sc.nextDouble();
double result = 0;
switch (operator) {
case "+":
result = firstNumber + secondNumber;
break;
case "-":
result = firstNumber - secondNumber;
break;
case "*":
result = firstNumber * secondNumber;
break;
case "/":
if(secondNumber == 0){
System.out.println("被除数不能为0");
}else {
result = firstNumber / secondNumber;
}
break;
default:
break;
}
System.out.println("最终结果是:"+ result);
}
}
面试官评价:效果是做出来了,但却有很多不足
1.懒洋洋同学你是典型初学者代表,就是碰到问题就直觉的用计算机能够理解的逻辑来描述和表达待解决问题
及具体的求解过程,你是典型的面向过程思维,你现在这种思维只能满足实现当前的需求,程序不易维护,复用
扩展,灵活性也不好!
2.没有理解题意,本帅气博主要求你用面向对象,你在干啥啊,Go out and turn right. 下一位
1.2 沸羊羊
public class Demo2{
public static void main(String[] args) {
//业务的封装:让页面逻辑和界面逻辑分开!
Scanner sc = new Scanner(System.in);
System.out.println("请输入第一个数:");
double firstNumber = sc.nextDouble();
sc.nextLine();
System.out.println("请输入运算符:");
String operator = sc.nextLine();
System.out.println("请输入第二个数:");
double secondNumber = sc.nextDouble();
double result = OperatorInner.getResult(firstNumber, secondNumber, operator);
System.out.println(result);
}
}
//运算类
class Operator {
private Operator() {}
public static double getResult(double firstNum, double SecondNum, String operator) {
double result = 0;
switch (operator) {
case "+":
result = firstNum + SecondNum;
break;
case "-":
result = firstNum - SecondNum;
break;
case "*":
result = firstNum * SecondNum;
break;
case "/":
result = firstNum / SecondNum;
break;
default:
break;
}
return result;
}
}
面试官评价: 比起上一位好点,知道将业务逻辑和界面逻辑分离,让它们之间的耦合度下降,只有分离开,才可以达到容易维护和 扩展,也知道将业务逻辑封装了一下(显示了面向对象中的封装),但还没到炉火纯青的地步,但是有一点就是如 果我现在新增了一个需求就是加一个 “”开平方根的运算“” 到时候要得改switch中的代码,你想想,你只是想加一个 开平方的运算,却需要让“加减乘除”运算都得参与编译,就违反了开闭原则。
1.3 喜洋洋
a.运算抽象类
public abstract class Operator{
protected double firstNumber;
protected double secondNumber;
public abstract double getResult();
}
b.加减乘除类
public class OperationAdd extends Operator {
@Override
public double getResult() {
return firstNumber + secondNumber;
}
}
public class OperationSub extends Operator{
@Override
public double getResult() {
return firstNumber - secondNumber;
}
}
a.简单工厂类
//简单工厂模式
public class OperationFactory {
public static Operator2 createOperator(String operatorStr) {
Operator2 operator = null;
switch (operatorStr) {
case "+":
operator = new OperationAdd();
break;
case "-":
operator = new OperationSub();//多态: 父类引用指向子类对象!!
break;
case "*":
break;
case "/":
break;
default:
break;
}
return operator;
}
}
d.测试类:
class Test{
public static void main(String[] args) {
Operator2 operator = OperationFactory.createOperator("-");
operator.firstNumber = 10;
operator.secondNumber = 30;
double result = operator.getResult();
System.out.println(result);
}
}
附带UML类图:
面试官评价:这位同学very good,熟练了运用了面向对象三大特征,还运用了简单工厂模式,
这下使的代码提升了一个档次,如果想要加 “开平方的算法” 就只需继承OPerator类,重写getResult方法即可,
非常符合开闭原则具有良好的扩展性,业务逻辑和界面逻辑也很好的分离了,嗯,我很满意,以后公司的厕所就包 给你了
补充:用个故事说明面向对象的好处!
长话短说,三国时期,曹操很高兴作了一句诗,喝酒唱歌,人生真爽
一个臣子命令木匠去刻字,木匠没吃没喝用了一天的时间刻好了,曹操看了看,用喝酒唱歌好像有点俗气
就换成了对酒当歌,人生真爽 ,臣子要命令木匠去刻,木匠只好把上次的扔掉,重新拿块板子刻,又是一天一夜,
终于刻好了,然后拿给曹操看,曹操看了看觉得还是不行,然后要修改了一下变成,对酒当歌,人生几何!
臣子要命令木匠去刻,木匠几乎要绝望了。这是还没出现活字印刷
如果出现了活字印刷术
1. 要改的话,只需改要改之字,此为可维护
2. 这些字并非用完这次就没用了,完全可以在后来的印刷中复用,此为可复用
3. 此诗若要加字的话,完全再刻一个添上即,此为可扩展,不像刻板印刷一样,要得重新去刻,费时费力
4. 字的排列可能是竖排可能是横排,此时只需将活字移动即可满足需求:此为灵活性好
注:刻板印刷 和 活字印刷 【后者比前者好太多了!!】
这篇其实没有过多的讲解简单工厂模式,大部分其实还是围绕 “面向对象” 的思想来说的