OOD Object Oriented Design 面向对象设计 01

OOD 和 SD的面试准备对象

Object Oriented DesignSystem Design
应届毕业生,SDEI-有经验的面试者,SDE1+
OOD常被当做考察面试者综合素质的标准需要处理大量数据,提供Service的部门
Amazon, Uber,.Facebook, Twitter,…
Viability 设计的系统,支持所有功能Scalability 设计是否支持不同规模的访问
-例子--例子-
Design Elevator SystemDesign Twitter

面试频率

Phone interview 低
Onsite interview 中高频

OOD 面公司
Amazon, Bloomberg, TripAdvisor, EMC, Uber…

SOLID 原则

单一责任原则

三角形面积计算例子

public class AreaCalculator{
    private float result;
    private  float getResult();

    public float getResult(){
        return this.result;
    }
    public float calculateArea(Triangle t){
        this.result = h * b / 2;
    }
}

增加功能让三角形 的面积 以 jason格式打印出来

违反单一原则的错误示范

public class AreaCalculator{
    private float result;
    private  float getResult();

    public float getResult(){
        return this.result;
    }
    public float calculateArea(Triangle t){
        this.result = h * b / 2;
    }
    
    public void printResultInJson(){
        jasonPrinter.intialize();
        jasonPrinter.print(this.result);
        jasonPrinter.close();
    }
}

这个类的功能 就是计算三角形面积
这里除了 计算面积
还增加了 第二个责任, 以json形式打印出来
让这个类变得臃肿了。
而且执行了许多 它本身不应该做的事情。

正确做法

分为两个类
一个计算 面积

另一个负责 将面积 以 float形式打印出来

public class AreaCalculator{
    private float result;
    private  float getResult();

    public float getResult(){
        return this.result;
    }
    public float calculateArea(Triangle t){
        this.result = h * b / 2;
    }
}

public class Printer{
    public printInJson(float number){
        jsonPrinter.intialize();
        jsonPrinter.print(this.result);
        jsonPrinter.close();
    }
}

Open Close Principle 开放封闭原则

对象或实体应该对扩展开放,
对修改封闭 (Open to extension, close to modification).

错误示范

public class AreaCalculator{
    private float result;
    private  float getResult();

    public float getResult(){
        return this.result;
    }
    public float calculateArea(Triangle t){
        this.result = h * b / 2;
    }

    public float calculateArea(Rectangle t){
        this.result = h * b;
    }
}
 

Liskov substitution principle 里氏替换原则

任何一个子类或派生类应该可以替换它们的基类或父类

Interface segregation principle 接口分离原则

不应该强迫一个类实现它用不上的接口

错误示范

public class Shape{
    abstract public float calculateVolumn();
    abstract public float calculateArea();
}


public class Rectangle extends Shape{
    //...
}

public class Cube extends Shape{
}

三角形 继承 Shape就不合理了,因为三角形没有Volumn
但是Cude可以继承

正确修改
两个类
一个计算平面的Shape
一个计算立体的Shape

Dependency inversion principle 依赖反转原则

抽象不应该依赖于具体实现,
具体实现应该依赖于抽象 High-level的实体不应该依赖于low-level的实体

public class AreaCalculator{
    private float result;
    private Triangle t;
    
    public float getResult(){
        return this.result;
    }
    
    public float calculateArea(){
        this.result = t.h * t.b / 2;
    }
}
public interface Shape {
    public float getArea();
}

public class Triangle implements Shape{
    public float getArea(){
        return b * h / 2;
    }
}


public class AreaCalculator {
    private float result;
    
    private float getResult(){
        return this.result;
    }
    
    public float calculateArea(Shape s){
        this.result = s.getArea();
    }
} 

例子

galss of water

首先,消除 疑惑,clarify 确认我们要设计的问题

万能技巧

双W解题法

What

找题目中的关键字
什么样的杯子
什么样的水

杯子的功能
水的特点

另一个例子

针对一个buiding 设计 一个elevator
关键字 Elevator Building

elevator 有什么特点
building 有什么特点

elevator 
新手问题:
电梯的载重:电梯能容纳多少人,承载多少重量
老手问题:
电梯有没有承重限制
如果有的话,如何知道当前电梯重量的限制

客梯 airstairs
货梯 goodselevator

是否需要设计两种类,如果需要,他们之间的关系是什么?

airsstairs 和 goodselevator之间称重
airstairs 和 goodselevator 能否上的层数相同

楼有多大
楼有多高
楼能容纳多少人

Buidling
是否有 多处能搭乘的电梯口?

当收到一个搭乘电梯请求时候,有多少电梯响应?

How

针对题目主题 提问,明确自己解题方向

对于电梯运行,有什么规则?
电梯有哪些规则?
如何判断电梯是否超重?
Passenger class 包含重量
电梯能否 自动感应当前重量

当按下按钮,哪一台电梯会相应?

response to the request
同方向 > 静止 > 反向
一半负责 奇数, 一半负责 偶数。

corner case
电梯运行,是否可以按 反方向的楼层?

Core Object

core object: 为了完成设计,需要定义的类

和面试官初步的纸面 contract

承上启下,来自Clarify的结果
为画类图 打下基础。

如何定义Core Object

两个方式

  1. 以一个Object作为基础,线性思考
  2. 确定Objects之间的映射关系

第一个写 的是设计的主体

在这里插入图片描述
展开线性思考:
输入是什么
输出是什么

输入:
按一下按钮
传入request
在这里插入图片描述
输出:
Elevator响应
电梯里面还有button

在这里插入图片描述

思考对应关系

1-1对应
1-n对应
n-n对应

request 和 elevatorSystem没有对应
request只是 发送给elevatorSystem

elevatorSystem 对应多个elevator
在这里插入图片描述

elevator 和 elevatorbutton对应

在这里插入图片描述

小结:
定义 ElevatorSystem
定义输入
定义输出
它们之间关系

UML类图标志

- 表示 access modifier
 访问修饰符
	package
	public
	private
	protected

package
在同一个package下可以访问,不声明,默认package level水平。

如果什么都不声明,变量和函数都是package level visible的,在同一个package内的其他类都可以访问
在这里插入图片描述
在面试当中,不管写代码,还是画类图,都不要用package level

public
如果声明为public,变量和函数都是public level visible的,任何其他的类都可以访问

在这里插入图片描述

private

如果声明为private,变量和函数都是class level visible的,这是所有access modifier中限制最多的一个。仅有定义这些变量和函数的类自己可以访问。

OOD当中 实现封装(encapsulation)的重要手段。

在这里插入图片描述

protected

如果声明为protected,变量和函数在能被定义他们的类访问的基础上,还能够被该类的子类所访问。

protected 实现继承的 重要手段。

在这里插入图片描述
这里,在子类 StreamingAud ioPLayer 是子类,其中没有定义
但是可以调用 speak.open()
说明 子类继承了父类

Use Cases

利用定义的Core Object, 列举出每个Object对应产生的use case。
每个use case只需要先用一句简单的话来描述即可。

ElevatorSystem
实现事情
Handle request

Request

Elevator
take external request 外部传入
take internal request 内部按钮
Open gate 开门
Close gate 关门

ElevatorButton
Press button

Class

在这里插入图片描述

在这里插入图片描述

阶段总结

  1. 澄清问题 what how
  2. 确定设计哪些类
  3. use cases

Class

类图

在这里插入图片描述

为什么画类图

可交付,Minimal Viable Product
节省时间,不容易在Coding上挣扎
建立在Use case上,和之前的步骤层层递进,条例清晰,便于交流和修改
如果时间允许/面试官要求,便于转化成Code

怎么画类图

遍历你所列出的use cases

对于每一个use case,更加详细的描述这个use case在做什么事情 。
(例如:take external request ->
ElevatorSystem takes an external request, and decide to push this request to an appropriate elevator)

针对这个描述,在己有的Core objects里填充进所需要的信息。

Use case: Handle request

ElevatorSystem takes an external request, and decide to push this request to an appropriate elevator

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值