面向对象六大原则 和 几种设计模式

面向对象的六大原则

单一职责原则

1)类的功能应该尽量细化分开,降低功能扩展时的难度;

2)类不应该实现不需要的(或其他模块的)功能;

ps.单一职责原则不仅仅适用于面向对象编程,也适用于模块的实现。

接口隔离原则

1)接口的抽象的功能应该尽量细化分开,不要让实现了这个接口的类必须实现它不需要的功能;

【接口隔离原则】和【单一职责原则】比较

我的理解是,单一职责原则关注实现,而接口隔离原则关注抽象,前者希望在实现时把功能细化,后者希望在抽象时就细化。此外,各种面向对象原则和不同的设计模式,有时候会觉得实现上甚至概念上都有些类似;面向对象原则主要是关注抽象和实现的不同,设计模式呢,因为目的不同,一是实现的细节稍微有一丁点不同(比如代理模式和包装模式,都是A-has-B的聚合关系的体现,但代理模式一般不要求A和B需要实现共同的接口或继承共同的父类;而包装模式由于功能上分类是相同的,所以A和B需要继承共同的父类或实现共同的接口,通过依赖倒置来实现功能的扩展),二是目的不同也就意味着功能的不同,需要考虑单一职责原则。

依赖倒置原则

1)尽量依赖于抽象而不是具体的实现

说白了就是尽量用接口或者父类来引用对象,对于新功能的扩展和不同功能多态性的实现很有帮助。

 

class A{
}

class B extends A{
        
}
class C extends A{
        
}

class X {
    public void func(A obj){
    }
    public void main(){
          func(new B());
          func(new C());
    }      
}    

ps。说到新功能的扩展,我就想起了轮子哥说的:设计模式就是用来解决频繁变更的需求的。新功能的扩展,如果成本不高的,一般是直接修改类,如果成本过高,就需要用设计模式来扩展甚至修改的功能。

里氏替换原则

1)可以用父类或者父接口的地方,一定可以用子类;

 

class A{
}

class B extends A{
        
}
class C extends A{
        
}

class X {
    
    public void main(){
          A a1 = new B();
          A a2 = new C();    
    }      
} 

 

依赖倒置原则和【里氏替换原则】比较

我的理解,一个比较关注抽象,一个比较关注实现。其实概念上很接近。

开闭原则

1)对扩展开放,对修改关闭

尽量在不修改原有的类的前提下,扩展功能。当然这视成本而定,一般还是直接修改类的,除非关联到了太多其他相关的内容,牵一发动全身。

聚合复用原则

1)尽量使用聚合而不是继承,或者说不要滥用继承

迪米拉法则

模块内部的实现细节不向外公开,模块和模块之间的交互方式越简单越好,模块尽量不干涉另外一个模块。

 

设计模式

代理模式

为什么不先说单例,工厂模式那些,因为之前看过了,今天写今天看的,另外的改天再写。

代理类A通过持有另一个对象B来使用B的功能,而不是直接去调用B的方法,这是为了更好地使用B的功能

public class B {

    public void func1() {}
    public void func2() {}
}
/**
 * 代理类
 * @author Administrator
 */
public class Agent {
    private B b;
    public Agent(B b) {
        this.b = b;
    }
    public void AgentDoSomething() {
        b.func1();
        b.func2();
    }
}

包装模式(适配器模式/装潢模式)

通过聚合组合的方式扩展类的功能。

public interface A {

    public void a();
    
}
public class B implements A{

    @Override
    public void a() {
        // TODO Auto-generated method stub
        System.out.println("初始功能");
    }
}
public class C implements A{
    private A obj ;
    public C(A obj)
    {
        this.obj = obj;
    }
    @Override
    public void a() {
        // TODO Auto-generated method stub
        obj.a();
        System.out.println("添加了功能");
    }
    
}
public class Main {
    
    public static void main(String[] args)throws Exception {
        A b = new B();
        A c = new C(b);
        b.a();
        c.a();
    }
}

输出结果

初始功能
初始功能
添加了功能

 【代理模式】和【包装模式】比较

两者的实现方式基本没什么不同,唯有A-has-B中,A和B是否需要继承同一个父类或实现了同一个接口

 

posted @ 2018-01-05 00:07  shadow_demo  阅读(1018)  评论(0)    收藏  举报