小皮博客 | Xiaopi's Blog

8-OO与设计模式-1

面向对象与设计模式的培训素材。
第一部分 面向对象设计原则

背景

  • 面向对象设计原则是设计模式的基础,也是设计模式的目的。
  • 设计模式是基于面向对象设计原则的最佳实践,是实现原则的方法

设计原则

单一职责原则(SRP)

就一个类而言,应该只专注于做一件事,仅有一个引起它变化的原因。

/** Bad Sample */
public interface BoyWithGirl {  
    void loveSomeGril();  
    void talkWithSomeGirl();  
}  
/** Bad Sample ? 每当Xiaoding要记录与一个女孩的关系时,
都得实现下面两个方法 */
public class XiaodingWithGirl implements BoyWithGirl {
    @Override
    public void loveSomeGril() {
    }
    @Override
    public void talkWithSomeGirl() {
    }
}
/** Good Sample */
public interface CommonFriend {
    void talkWithSomeGirl();
    void listenToSomeGirl();
}
public interface GirlFriend extends CommonFriend {
    void loveWithTheGirl();
}

开放&封闭原则(OCP)

软件实体应当对扩展开放,对修改关闭,即软件实体应当在不修改的前提下扩展。

/** Bad Sample */ 
public enum GetAloneType {
    watchMove, eat;
} 
public class GetAloneWithGirl {
    public void watchMovie() {}
    public void  eat(){}    
    public void  kiss(){}
}
public class GetAloneWithLily {
    private GetAloneWithGirl getAloneWithLily;
    public void getAlone(GetAloneType type) {
        switch (type) {
        case watchMove:
            getAloneWithLily.watchMovie();
        case eat:
            getAloneWithLily.eat();
        default:
            return;
        }
/** Good Sample */
public enum GetAloneType {  
watchMove, eat, kiss;
}
public interface GetAloneWithGirl {
    void activities();
}
public class EatWithGirl implements GetAloneWithGirl {
    @Override
    public void activities() {    }
}
public class WatchMovieWithGirl implements GetAloneWithGirl {
    @Override
    public void activities() {}
}
public class KissWithGirl implements GetAloneWithGirl {
    @Override
    public void activities() {}
}

public class GetAloneWithGanlulu {

    private GetAloneWithGirl withGanlulu;

    public void getAlone(GetAloneType type) {
        switch (type) {
        case watchMove:
            withGanlulu= new WatchMovieWithGirl();
        case eat:
            withGanlulu= new EatWithGirl();
        case kiss:
            withGanlulu= new KissWithGirl();
        }
        withGanlulu.activities();
    }

}

里氏替换原则(LSP)

  • 如果对于类型S的每一个对象o1,都有一个类型T的对象o2,使对于任意用类型T定义的程序P,将o2替换为o1,P的行为保持不变,则称S为T的一个子类型。
  • 子类型必须能够替换它的基类型。LSP又称里氏替换原则。
  • 对于这个原则,通俗一些的理解就是,父类的方法都要在子类中实现或者重写。
/** Bad Sample */ 
public interface Duck {
    void guagua();
    void floating();
}
public class ChinaDuck implements Duck {
    @Override
    public void guagua() {}
    @Override
    public void floating() {}
}
/* 橡皮鸭不会叫*/
public class RubberDuck implements Duck {
    @Override// 不能覆盖
    public void guagua() {
    }
    @Override
    public void floating() {
    }

}
/** Good Sample */
public interface BarkableDuck {
    void guagua();
}
public interface DuckLike {
    void floating();
}
public class RubberDuck implements DuckLike {
    @Override
    public void floating() {
    }
}
public class ChinaDuck implements DuckLike, BarkableDuck {
    @Override
    public void guagua() {}
    @Override
    public void floating() {}
}

依赖倒置原则

  • 高层模块不应该依赖于低层模块,二者都应该依赖于抽象。
  • 抽象不应该依赖于细节,细节应该依赖于抽象。

接口隔离原则

  • 使用多个专门的接口比使用单一的总接口要好。
  • 一个类对另外一个类的依赖性应当是建立在最小的接口上的。
  • 一个接口代表一个角色,不应当将不同的角色都交给一个接口。没有关系的接口合并在一起,形成一个臃肿的大接口,这是对角色和接口的污染。

权衡

在现实世界中确实存在着必须依赖细节的事物,比如法律,就必须依赖细节的定义。 “杀人偿命”在中国的法律中古今有之,那这里的杀人就是一个抽象的含义,怎么杀,杀什么人,为什么杀人,都没有定义,只要是杀人就统统得偿命,那这就是有问题了,好人杀了坏人,还要陪上自己的一条性命,这是不公正的,从这一点看,我们在实际的项目中审时度势,不要抓住一个原则不放,每一个原则的优点都是有限度的,并不是放之四海而皆准的真理,所以别为了遵循一个原则而放弃了一个项目的终极目标:投产上线和盈利。技术只是实现目的的工具,设计做得再漂亮,代码写得再完美,项目做得再符合标准,一旦项目亏本,产品投入大于产出,那整体就是扯淡!

软件工程设计原则

为了避免混淆,这里将软件工程的设计原则在此讲述一下。

  • 最小成本原则
  • 安全性和可靠性原则
  • 先进性和成熟性原则
  • 实用性、易用性原则
  • 统一及一致性原则
  • 用户体验优先原则
  • 数据统一和完整性原则
  • 可扩展性原则

版权声明

本文标题:8-OO与设计模式-1

文章作者:盛领

发布时间:2015年03月04日 - 12:16:31

原始链接:http://blog.xiaoyuyu.net/post/cfa5d305.html

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

如您有任何商业合作或者授权方面的协商,请给我留言:sunsetxiao@126.com

盛领 wechat
欢迎您扫一扫上面的微信公众号,订阅我的博客!
坚持原创技术分享,您的支持将鼓励我继续创作!