一些OO练习

来源:互联网 发布:nginx 并发连接数设置 编辑:程序博客网 时间:2024/05/16 14:32

表达式:1 + 2 * 3

Expression = {literal | Expression}

interface Expression { int eval();}

子类 LiteralExpression, CompoundExpression,后者分运算符表达式OperatorExpresion,函数表达式FunctionExpression,运算符表达式又分单目双目

双目运算符表达式,有2个operand,类型是Expression

abstract class DoubleOperandExpression  implments Expression{Expression  firstOperand;Expression secondOperand;public abstract operatorFunc(Expression a, Expresson b);public int eval() {return operatorFunc(first Operand, secondOperand);}}class AddOperatorExpression extends DoubleOperandExpression {public int operatorFunc(Expression a, Expression b) {return a.eval() + b.eval();}}

机场调度系统

类:ControlTower, Plane, Schedule, Lane

关系:ContorlTower 和Lane以及Schedule都是一对多的关联关系,Schedule和Plane是一对一关系,Schedule 单向关联 Plane, Plane作为一个类,schedule不是它的固有属性。Plane对Lane有一对一的依赖关系(局部变量)

驱动控制:主动对象就是ControlTower,根据schedule顺序调度Plane,给Plane发命令消息

class ControlTower {PriorityQueeue<Schedule> schedules;Lane[] lanes;Object signal = new Object();public addSchedule(Schedule s) {schedules.offer(s);signal.notify();}public cancelSchedule(Schedule s) {schedules.remove(s);}public void run() {while (!airPort_shutdown) {Schedule s = schedules.poll(); //bloked if no schedulewhile (s.time > Now()) {signal.wait(Now() - s.time);if (s.time > schedules.peek().time) {schedules.offer(s);s = schedules.poll();}}Lane lane = getFreeLane();Plane plane = s.plane;plane.moveTo(lane);plane.takeOff();releaseLane(lane);}}public addSchedule(Schedule s) {schedules.offer(s);}public cancelSchedule(Schedule s) {schedules.removde(s);}}

3 货车追踪系统Truck Tracking System

类:Truck, 送货单,TrackingSystem,  Log, DB

关系:Truck 一对多 送货单, TrackingSystem 一对多 Truck,一对一DB

消息交互:Truck 定时向 System发送 Log (TruckId, GPS, time),  后者SaveToDB

工作人员向system发送查询请求 List<Log>query(truckId, startTime, endTIme)

驱动控制:Truck是一个主动对象:处理自己携带的送货单,直到处理完毕。

TrackingSystem:接受truck和 查询人员的查询消息,

4 21点游戏

庄家轮流问每个人要不要,直到所有人都不要,然后判断谁赢,然后下一次游戏。

类庄家Game21Points, Player

数据都封装在庄家类里

消息互动:庄家问Player要不要,庄家通知Player win

驱动控制:只有庄家是主动对象,单线程。

Class Game21Points {boolean in[NUM_PLAYER];int points[NUM_PLAYER];Player players[NUM_PLAYER];Deck deck;void run () {while (!closed) {for (int player = 0; player < NUM_PLAYER; ++player) {in[player] = true;points[player] = 0;}int numOfIn = NUM_PLAYER;deck.shuffle();while(numOfIn > 0) {for (int player = 0; i < NUM_PLAYER; ++player) {if (in[player] == true) {if (players[i].needMore()) {points[player] += deck.next();if (points[player] > 21) {in[player] = false;points[player] = 0;--numOfIn;}}elsein[player] == false;}}}judge();}}void judge(){int player = getMax(points);player.win();}}

Cache

对象:Cache(服务接口类,也是(Mediator),Item(封装用户data)Index(负责查找data位置),Store,负责根据位置取出Item,再返回给用户。

interface Cache<K, V> {V get(K key);  void put(K key, V value);}

interface Item<K,V>  {K getKey(); V getValue();}

interface Index { Location getLocation(K key); void removeIndex(K key); void updateIndex(k key);}

interface Store { Item takeOut(Location pos);   Item get(Location pos); void append(Item item) }

interface CacheWithExpireStategy {}

关于最精髓的LRU策略是封装到Store里还是由上层Cache类负责?原则是:单一责任。Store的责任就是简单的仓库管理操作,这样不同的过期策略只是建立在store上层的策略。整体中如果有部分是可变的,那么这个可变的部分就应该独立出来作为一个组件,每个组件都是不变的,单一行为的。可变的部分是通过多态实现,可以插拔不同组件,但是组件是不变的,对修改关闭。

Cache和不同策略啥关系,可以继承,比如LRUCache, LFUCache, 也可以委托(聚合) Cache委托内部封装的LRUStrategy去实际操作。这是经典泛化 vs 聚合的问题,前者是结构层面的,后者是动态的,也就是一个Cache可以支持不同的策略


凡是涉及数据管理的系统,都可以用图书馆来考虑,都要面临图书的位置查找和实际摆放两个问题,对应的两大组件就是就是index + store,所有的数据管理系统都包含这两部分。


邮件系统

思路,不像电梯那样有现实世界的对应,先use case 分析

系统边界:

1)外埠邮件收发:向外埠server投递,接受外部server的投递

2)邮件客户端收发:收信,发信

3)webMail

结构:

核心是一个目录和文件管理系统,加上不同的访问渠道。就是一个典型的基础API 外加上层应用的结构。








0 0
原创粉丝点击