工作两年多了,学了各种东西,android、html5、css、js、大数据、java后端,工作的坎坷,最后还是打算从事java后台,博而不精,面试有点小困难,虽然每次面试过后越来越好,但是达不到自己最想要去的公司和工作。面试了某家大型公司,最后面试官说,你工作两年了还是个初级工程师,不管技术如何更新,基础才是最重要,事情总要人去做,虽然最终落榜。沉静下来,两个月初看完了《java编程思想》、《深入理解java虚拟机》,心里大概有个底,知道什么技术解决什么问题,过段时间再看一次,知道完全理解为止,期间也看了炒股方面的书:《聪明的投资者》(美)本杰明·格雷厄姆、《在股市大崩溃前抛出的人:巴鲁克自传》、《巴菲特基金投资6招》刘建位 徐晓杰、《长盈之道》约翰.博格。现在开始学习设计模式《大话设计模式》,感谢程杰老师写的这本书。
下面的例子主要来自《大话设计模式》:
小菜面试时,要求用任何一种面相对象的设计语言c#、java、python等写一到计算器题目。小菜十分钟不到就写完了。程序如下:
(一)封装
小菜说:“我实在想不出这么小的程序如何用继承和多态”。
大鸟说:“慢慢来,你要学的东西多着呢,你好好想想”。
第二天,小菜说:“这么小的计算器程序怎么用到面向对象的三个特性啊!继承和多态怎么用得到我实在想不出来”。
大鸟说:“很有钻研精神嘛,你昨天写的程序能够做到灵活的可修改和扩展呢?如何增加开根(sqrt)运算”
小菜说:“在Calculator类中,switch增加一个分支就行了啊”
大鸟说:“问题是你要加一个平方根运算,却需要让加减乘除运算都得参加编译,如果不小心把加法改成了减法,这岂不是大大糟糕。比如公司让你更改一个人员层级薪资的运算,还要给你各个管理层的运算代码,你对自己的薪资不满意,稍加修改,不是问题很大了。”
(二)继承
下面的例子主要来自《大话设计模式》:
小菜面试时,要求用任何一种面相对象的设计语言c#、java、python等写一到计算器题目。小菜十分钟不到就写完了。程序如下:
import java.util.Scanner;
public class Program {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println("请输入第一个数字:");
String numberOne = sc.next();
System.out.println("请输入计算符:");
//用于jdk1.7之前 获取char
//char calcChar = sc.next().charAt(0);
// 用于jdk1.7及之后
String calcChar = sc.next();
System.out.println("请输入第二个数字:");
String numberTwo = sc.next();
int result = 0;
try {
// jdk 1.7之前只能使用int 、short 、byte 、char。jdk 1.7及之后可以使用String。本示例采用jdk 1.8
switch (calcChar){
case "+":
result = Integer.parseInt(numberOne) + Integer.parseInt(numberTwo);
break;
case "-":
result = Integer.parseInt(numberOne) - Integer.parseInt(numberTwo);
break;
case "*":
result = Integer.parseInt(numberOne) * Integer.parseInt(numberTwo);
break;
case "/":
result = Integer.parseInt(numberOne) / Integer.parseInt(numberTwo);
break;
default:
throw new RuntimeException("计算符输入错误");
}
}catch (Exception e){
e.printStackTrace();
System.out.println("分母不能为0,或者数字输入错误,或者计算符输入错误");
System.exit(0);
}
System.out.println("运算结果为:" + result);
}
}
小菜面试完之后便跟表哥大鸟说起了这件事,大鸟说:你感觉写得怎么样,理解了面试题目的真正意思没。小菜说了自己如何如何(小菜最后当然落榜了)。大鸟就说:人家要求用面向对象语言进行设计,面向对象的特性:封装、继承、多态,界面应该要和业务分开,以后无论是手机端、web端、pc端都能公用。你达到了没。小菜想了想,就改成了如下的程序:
(一)封装
import java.util.Scanner;
public class Program {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println("请输入第一个数字:");
String numberOne = sc.next();
System.out.println("请输入计算符:");
//用于jdk1.7之前 获取char
//char calcChar = sc.next().charAt(0);
// 用于jdk1.7及之后
String calcChar = sc.next();
System.out.println("请输入第二个数字:");
String numberTwo = sc.next();
int result = 0;
try {
result = Calculator.calc(Integer.parseInt(numberOne),calcChar,Integer.parseInt(numberTwo));
}catch (Exception e){
e.printStackTrace();
System.out.println("分母不能为0,或者数字输入错误,或者计算符输入错误");
System.exit(0);
}
System.out.println("运算结果为:" + result);
}
}
class Calculator {
public static int calc(int numberOne,String calcChar, int numberTwo)throws Exception{
int result = 0;
// jdk 1.7之前只能使用int 、short 、byte 、char。jdk 1.7及之后可以使用String。本示例采用jdk 1.8
switch (calcChar){
case "+":
result = numberOne + numberTwo;
break;
case "-":
result = numberOne - numberTwo;
break;
case "*":
result = numberOne * numberTwo;
break;
case "/":
result = numberOne / numberTwo;
break;
default:
throw new RuntimeException("计算符输入错误");
}
return result;
}
}
大鸟看了之后说:”孺子可教也,实现了界面和业务的分离,用了封装这个特性,面向对象还有两个特性没用“。
小菜说:“我实在想不出这么小的程序如何用继承和多态”。
大鸟说:“慢慢来,你要学的东西多着呢,你好好想想”。
第二天,小菜说:“这么小的计算器程序怎么用到面向对象的三个特性啊!继承和多态怎么用得到我实在想不出来”。
大鸟说:“很有钻研精神嘛,你昨天写的程序能够做到灵活的可修改和扩展呢?如何增加开根(sqrt)运算”
小菜说:“在Calculator类中,switch增加一个分支就行了啊”
大鸟说:“问题是你要加一个平方根运算,却需要让加减乘除运算都得参加编译,如果不小心把加法改成了减法,这岂不是大大糟糕。比如公司让你更改一个人员层级薪资的运算,还要给你各个管理层的运算代码,你对自己的薪资不满意,稍加修改,不是问题很大了。”
(二)继承
class Calculator {
private int numberOne;
private int numberTwo;
public int getNumberOne() {
return numberOne;
}
public void setNumberOne(int numberOne) {
this.numberOne = numberOne;
}
public int getNumberTwo() {
return numberTwo;
}
public void setNumberTwo(int numberTwo) {
this.numberTwo = numberTwo;
}
public int getResult(){
int result = 0;
return result;
}
}
class AddCalculator extends Calculator{
@Override
public int getResult() {
return getNumberOne() + getNumberTwo();
}
}
class SubCalculator extends Calculator{
@Override
public int getResult() {
return getNumberOne() - getNumberTwo();
}
}
class MulCalculator extends Calculator{
@Override
public int getResult() {
return getNumberOne() * getNumberTwo();
}
}
class DivCalculator extends Calculator{
@Override
public int getResult(){
if(getNumberTwo() == 0)
throw new RuntimeException("除数不能为0");
return getNumberOne() / getNumberTwo();
}
}
大鸟说:“写得不错嘛,大大超过了我的预想,你现在未解决的问题就是去实例化的问题,采用“简单工厂模式”就可解决”。
import java.util.Scanner;
public class Program {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println("请输入第一个数字:");
String numberOne = sc.next();
System.out.println("请输入计算符:");
//用于jdk1.7之前 获取char
//char calcChar = sc.next().charAt(0);
// 用于jdk1.7及之后
String calcChar = sc.next();
System.out.println("请输入第二个数字:");
String numberTwo = sc.next();
int result = 0;
try {
Calculator calculator = CalculatorFactory.createCalculator(calcChar);
calculator.setNumberOne(Integer.parseInt(numberOne));
calculator.setNumberTwo(Integer.parseInt(numberTwo));
result = calculator.getResult();
}catch (Exception e){
e.printStackTrace();
System.out.println("分母不能为0,或者数字输入错误,或者计算符输入错误");
System.exit(0);
}
System.out.println("运算结果为:" + result);
}
}
class Calculator {
private int numberOne;
private int numberTwo;
public int getNumberOne() {
return numberOne;
}
public void setNumberOne(int numberOne) {
this.numberOne = numberOne;
}
public int getNumberTwo() {
return numberTwo;
}
public void setNumberTwo(int numberTwo) {
this.numberTwo = numberTwo;
}
public int getResult(){
int result = 0;
return result;
}
}
class AddCalculator extends Calculator{
@Override
public int getResult() {
return getNumberOne() + getNumberTwo();
}
}
class SubCalculator extends Calculator{
@Override
public int getResult() {
return getNumberOne() - getNumberTwo();
}
}
class MulCalculator extends Calculator{
@Override
public int getResult() {
return getNumberOne() * getNumberTwo();
}
}
class DivCalculator extends Calculator{
@Override
public int getResult(){
if(getNumberTwo() == 0)
throw new RuntimeException("除数不能为0");
return getNumberOne() / getNumberTwo();
}
}
class CalculatorFactory{
public static Calculator createCalculator(String calcChar){
Calculator calculator = null;
// jdk 1.7之前只能使用int 、short 、byte 、char。jdk 1.7及之后可以使用String。本示例采用jdk 1.8
switch (calcChar){
case "+":
calculator = new AddCalculator();
break;
case "-":
calculator = new SubCalculator();
break;
case "*":
calculator = new MulCalculator();
break;
case "/":
calculator = new DivCalculator();
break;
default:
throw new RuntimeException("计算符输入错误");
}
return calculator;
}
}
自己的感悟,以后碰到switch想想用这个方法改写。先做到“有剑胜无剑”,最后做到“无剑胜有剑”。