Tuesday, December 1, 2015

OOD Design Misc



Web Scalability for Startup Engineers
Principles of Good Software Design
SIMPLICITY
“Make things as simple as possible, but no simpler.” –Albert Einstein

It is about what would be the easiest way for another software engineer to use your solution in the future. It is also about being able to comprehend the system as it grows larger and more complex. The lessons of simplicity often come from experience with different applications, using different frameworks and languages. Revisiting code you have written, identifying complexity, and looking for solutions to simplify is the first step to learn from your own mistakes. Over time you develop sensitivity and an ability to quickly judge which solution is simpler in the long run. If you have an opportunity to find a mentor or work closely with people who value simplicity, you will make much faster progress in this area.

Hide Complexity and Build Abstractions
SCALING PRODUCTIVITY THROUGH AUTOMATION

The single most important practice promoting loose coupling is to carefully manage your dependencies.
When writing code, be stingy. Share only the absolute minimum of information and functionality that satisfies the requirements. Sharing too much too early increases coupling and makes changes more difficult in the future.

Avoiding Unnecessary Coupling
A great example of unnecessary coupling is the practice of exposing all the private properties using public getters and setters.

Another common example of unnecessary coupling is when clients of a module or class need to invoke methods in a particular order for the work to be done correctly. Sometimes there are valid reasons for it, but more often it is caused by bad API design, such as the existence of initialization functions. Clients of your class/module should not have to know how you expect them to use your code. They should be able to use the public interface in any way they want.

allowing circular dependencies between layers of your application, modules, or classes is a bad coupling practice.

Slf4j
DON’T REPEAT YOURSELF (DRY)
“I think one of the most valuable rules is avoid duplication. Once and only once, is the Extreme Programming phrase.” –Martin Fowler

Any time I am about to write a generic library I search online first and usually there are a few good open-source alternatives available.

Coding to contract, or coding to interface, is another great design principle. Coding to contract is primarily about decoupling clients from providers. By creating explicit contracts, you extract the things that clients are allowed to see and depend upon.

As a provider, exposing more than necessary increases your future costs because any time you want to make a change, you will need to renegotiate the contract with all of your clients (propagating the change throughout the system).

DRAW DIAGRAMS
“You know what architecture really is? It is an art of drawing lines. With an interesting rule that once you have drawn a line all the dependencies that cross that line point in the same direction.” –Robert C. Martin

Drawing diagrams is a must-have skill for every architect and technical leader.

By assuming the client’s point of view and drawing simple diagrams at the same time, you will validate your own design and discover flaws before the code is even written. Once you’re more comfortable with diagrams, attempt to do more up-front design.

use case, class, and module diagrams

Class diagrams are good for visualizing coupling, as each class becomes a node of the diagram and each dependency becomes a line. By drawing a class diagram, you see immediately which classes are highly coupled with the rest of the module and which are more independent. Simply watch how many lines are connected to each node to judge how many dependencies the node includes. Class diagrams are the best tools to visualize a module’s structure with its classes, interfaces, and their interdependencies.

module diagrams focus on the higher level of abstraction. Module diagrams represent the zoom-out view of the code, with less depth but more surface area.
module diagrams focus on relationships between larger parts of the system. You use module diagrams to show high-level dependencies and interactions between a module and its direct neighbors of the dependency graph.

As your system grows larger, it is better to create a few module diagrams, each focusing around certain functionality, rather than including everything on a single diagram.
ArgoUML, draw.io

Interfaces should only depend on other interfaces and never on concrete classes. Classes, on the other hand, should depend on interfaces as much as possible.

SINGLE RESPONSIBILITY
Keep class length below two to four screens of code.
Ensure that a class depends on no more than five other interfaces/classes.
Ensure that a class has a specific goal/purpose.
Summarize the responsibility of the class in a single sentence and put it in a comment on top of the class name. If you find it hard to summarize the class responsibility, it usually means that your class does more than one thing.

OPEN-CLOSED PRINCIPLE
“Good architecture maximizes the number of decisions not made.” –Robert C. Martin
The open-closed principle is about creating code that does not have to be modified when requirements change or when new use cases arise. Open-closed stands for “open for extension and closed for modification.”
The prime objective of this principle is to increase flexibility of your software and make future changes cheaper.
Examples
Comparator, Sorter
MVC framework


DEPENDENCY INJECTION
Dependency injection provides references to objects that the class depends on, instead of allowing the class to gather the dependencies itself. It allows classes to “not know” how their dependencies are assembled, where they come from, or what actual implementations are fulfilling their contracts.

When used well, dependency injection reduces local complexity of the class and makes it dumber, which is a good thing. Without knowing who the provider of the contract is or how to get an instance of it, our class can focus on its single responsibility. The code of the class becomes simpler, and it requires less understanding of the rest of the system to modify and unit test the class.

By removing the assembly code from your classes, you make them more independent, reusable, and testable.

INVERSION OF CONTROL (IOC)
Dependency injection is limited to object creation and assembly of its dependencies. Inversion of control, on the other hand, is a more generic idea and can be applied to different problems on different levels of abstraction.
Instead of you being in control of creating instances of your objects and invoking methods, you become the creator of plugins or extensions to the framework. The IOC framework will look at the web request and figure out which classes should be instantiated and which components should be delegated to.

IOC is also referred to as “the Hollywood principle” because the subject of IOC is being told, “Don’t call us, we will call you.” In practice, this means your classes do not have to know when their instances are created, who is using them, or how their dependencies are put together. Your classes are plugins, and some external force will decide how and when they should be used.

DESIGNING FOR SCALE
Adding more clones Adding indistinguishable components
Functional partitioning Dividing the system into smaller subsystems based on functionality
Data partitioning Keeping a subset of the data on each machine

Functional partitioning is most often applied on a low level, where you break your application down into modules and deploy different types of software to different servers.
use functional partitioning on a higher level of abstraction by creating independent services.

DESIGN FOR SELF-HEALING
“Any sufficiently large system is in a constant state of partial failure.” –Justin Sheehy
failure must be considered a norm, not a special condition.
always thinking about what else can fail and in what order.
Advocates of the Crash-Only approach say that the system should always be ready to crash, and whenever it reboots, it should be able to continue to work without human interaction. This means that the system needs to be able to detect its failure, fix the broken data if necessary, and start work as normal.

Systems that are not redundant need special attention, and it is a best practice to prepare a disaster recovery plan (sometimes called a business continuity plan) with recovery procedures for all critical pieces of infrastructure.

To give you an example of self-healing, consider failure handling in Cassandra, which is an open-source data store. In Cassandra, a data node failure is handled transparently by the system. Once the cluster recognizes node failure, it stops any new requests from being routed to the failed node. The only time when clients may be failing is during the failure recognition phase. Once the node is blacklisted as failed, clients can still read and write data as usual, as remaining nodes in the cluster provide redundancy for all of the data stored on the failed node. Whenever the failed node comes back online, it is brought up to speed with the data it missed and the system continues as if nothing happened.

In the same way, replacing a dead node with a brand-new, blank node does not require system administrators to reconstruct the data from backup, as is often necessary in relational database engines. Adding a new empty data node causes the Cassandra cluster to synchronize the data so that over time the newly added machine is fully up to date. When a system can detect its own partial failure, prevent unavailability, and fully fix itself as soon as possible, you have a self-healing system. Minimizing the mean time to recovery and automating the repair process is what self-healing is all about.

learn your craft, learn your tools, and look for reasons to drive your decisions.

http://www.1point3acres.com/bbs/thread-176958-1-1.html
1. 可读性——代码即使以后不被改动,也是有人要读的,如果一段代码三个月后作者自己都不知道写的是个什么玩意,必然不合格
2. 易扩展型——注意,是易扩展型,而不是扩展性。因为扩展性可能是一个不存在的问题,我们不应该为未来不存在的扩展浪费过多的时间,但是如果能够把代码组织成很容易改写成具有扩展性的代码,就可以在开发速度和维护性上做出一个平衡了。
3. 难改动性——想了想没有想到太好的词。这里的意思是说,通过组织代码的结构,使得未来的人难以做出危害代码质量的改动。举个简单的例子,在某个初始化函数里面我们初始化了三个有关联的成员变量,里面还夹了一坨逻辑,这时候把它们extract成一个method,给它一个有意义的名字,这样可以i)使得原有的逻辑不会因为后面的改动被打散,而变得不可读;ii)在增加逻辑的时候,后人会被这个method的名字所约束,不会破坏contract。当然如果你的初始化代码是纯逻辑的话这也是一个加入unit test的理想位置。
4. 无重复性——如果说写代码的时候有什么必须遵守的铁律,这就是其中一条。任何形式的重复代码都是绝不可取的,必须改掉。
5. 最后再推荐一本书,叫做《Refactoring: Improving the Design of Existing Code》,这本书并不是用来面试的,而是讲如何提高代码质量,避免写出烂代码。作为一名合格的程序员,不可不察。

http://www.1point3acres.com/bbs/forum.php?mod=viewthread&tid=138178&extra=page%3D1%26filter%3Dtypeid%26typeid%3D200%26typeid%3D200
先想想都涉及到什么物体(即名词),然后这些一般就是类。
然后想想继承,多态。比如都是车,但是有不同的类型,大小也会对停车位有影响。
Gayle的书里讲了停车场,但是那种复杂的停车场我不太懂,那停车场还分好多层。

听说amazon还问过棋类的设计。

http://www.1point3acres.com/bbs/forum.php?mod=viewthread&tid=136257&extra=page%3D1%26filter%3Dtypeid%26typeid%3D200%26typeid%3D200
URL shortener:

以后大家有课程project没思路,可以去实现tiny shortener哈。面试时又可以扯蛋,又可以当作课程project,一举多得哈
定义:http://en.wikipedia.org/wiki/URL_shortening 看了定义,感觉就是要设计短URL,就是长URL 关联 uniqie key ,  这些key 可通过 hash 函数和随机数产生器等产生
这篇文章介绍了我们自己如何实现一个url shortener(http://www.sitepoint.com/building-your-own-url-shortener/)。该文章实现tiny url用的是php。短url一般也就是数字和大小写字母组合在一起。比如1位有62种可能性,那么2位可以组合成62*62可能性,3位有62*62*62,4位即有14776336种 combinations了。可以想象当由10位组合成tiny url, tiny url可以有多少! 这篇文章介绍了如何设计数据库,如何创建url short code, 如何decode short code, 以及最后的如何拼接起来。

动态消息 (即news feed)

通过新闻来了解啥是 news feed: http://cn.engadget.com/2013/12/03/facebook-news-feed-update/ ,  http://36kr.com/p/201758.html

收集的Prep for Interview - System Design//OOD 资源
http://www.1point3acres.com/bbs/forum.php?mod=viewthread&tid=136401&extra=page%3D1%26filter%3Dtypeid%26typeid%3D200%26typeid%3D200
大话设计模式,度娘有
为数不多的中文介绍如何准备系统设计的
https://www.youtube.com/watch?v= ... jxp0fmqEv4tXMcl5xww

mitbbs 也有总结
http://www.mitbbs.com/article_t/JobHunting/32777529.html

http://blog.csdn.net/v_july_v/article/details/7382693
http://blog.csdn.net/sigh1988/article/details/9790337
http://www.1point3acres.com/bbs/forum.php?mod=viewthread&tid=83692&extra=page%3D1%26filter%3Dtypeid%26typeid%3D200%26typeid%3D200
最近在研究OOD的题目,这种题型在面试中非常常见。想请教一下大家,回答这种题型的时候,有什么规律和顺序吗?面试官一般希望看到怎么样的回答呢?比如说,先设计类,再设计每个类的属性和方法,是这个顺序吗?
Cracking the Coding Interview 这本书里有讲到的一些,可以去看看
先掌握几个基本的设计模式

最近有朋友推荐了 head first design pattern. 中文版的好像是北航出版的,叫《设计模式》

http://www.1point3acres.com/bbs/forum.php?mod=viewthread&tid=79544&extra=page%3D1%26filter%3Dtypeid%26typeid%3D200%26typeid%3D200
design pattern主要考虑设计的扩展,复用等,如何利用OO思想设计,但是OOD题目首先要考虑设计出来功能,比如停车场设计,LRU  这种,开放什么方法,写什么属性在Class中。如果是经验一般的人,弄完这些了才考虑用design pattern 重构,经验充足的当然一上来考虑当前模型适用什么design pattern了,但是如果new grad,没那么多开发经验,根本做不到。

推荐《大话设计模式》。这本书写得深入浅出,以至于我用了两天就看完了,明白了不少有用的设计模式

感觉OOD题目很需要我们先把需求了解清楚,用哪些类,要实现哪些方法,但一般没怎么用上design pattern,至少从CTCI那本书看来是这样

可以去crackingthecodinginterview.com ,在solution download里面作者给了她的github连接,里面有各种语言的解法,C++, JAVA, PYTHON的都有。

Example:
Rest API Design
http://www.1point3acres.com/bbs/forum.php?mod=viewthread&tid=134033&extra=page%3D1%26filter%3Dtypeid%26typeid%3D200%26typeid%3D200
Implement an API to access a bank.  Assume it will be a REST API using HTTP, but don’t worry about protocol processing.  Simply write the methods corresponding to API endpoints.

储蓄查询用@GET  链接里上ID
存钱用@PUT 幂等的 出了错 连续提交 你存多少钱都一个结果 我猜国内银行肯定这么干
取钱用@POST非幂等你出错多次取钱肯定给你都扣掉,我们银行能吃亏?(开玩笑的 一般交易都带流程号 只有一次能用 最好都是幂等安全)
开子户 服务 新建啥玩意用@PUT


Labels

Review (572) System Design (334) System Design - Review (198) Java (189) Coding (75) Interview-System Design (65) Interview (63) Book Notes (59) Coding - Review (59) to-do (45) Linux (43) Knowledge (39) Interview-Java (35) Knowledge - Review (32) Database (31) Design Patterns (31) Big Data (29) Product Architecture (28) MultiThread (27) Soft Skills (27) Concurrency (26) Cracking Code Interview (26) Miscs (25) Distributed (24) OOD Design (24) Google (23) Career (22) Interview - Review (21) Java - Code (21) Operating System (21) Interview Q&A (20) System Design - Practice (20) Tips (19) Algorithm (17) Company - Facebook (17) Security (17) How to Ace Interview (16) Brain Teaser (14) Linux - Shell (14) Redis (14) Testing (14) Tools (14) Code Quality (13) Search (13) Spark (13) Spring (13) Company - LinkedIn (12) How to (12) Interview-Database (12) Interview-Operating System (12) Solr (12) Architecture Principles (11) Resource (10) Amazon (9) Cache (9) Git (9) Interview - MultiThread (9) Scalability (9) Trouble Shooting (9) Web Dev (9) Architecture Model (8) Better Programmer (8) Cassandra (8) Company - Uber (8) Java67 (8) Math (8) OO Design principles (8) SOLID (8) Design (7) Interview Corner (7) JVM (7) Java Basics (7) Kafka (7) Mac (7) Machine Learning (7) NoSQL (7) C++ (6) Chrome (6) File System (6) Highscalability (6) How to Better (6) Network (6) Restful (6) CareerCup (5) Code Review (5) Hash (5) How to Interview (5) JDK Source Code (5) JavaScript (5) Leetcode (5) Must Known (5) Python (5)

Popular Posts