五个原则
单一职责原则
单一职责原则(SRP),对于一个类而言,应该仅有一个引起它变化的原因。通俗的说,一个类只能干一个事,只能承担一个职责。如果一个类承担的职责过多,等于把这些职责耦合在一起,这种耦合会导致设计十分的脆弱,当变化发生的时候,会遭到意想不到的破坏。
开放-封闭原则
开放封闭原则,简称开闭原则,指软件实体(类、模块、函数等等)应该可以扩展,但是不可修改。换句话说,对扩展开放,对更改封闭。但无论模块多么的封闭,都会存在一些无法应对的变化。因此,设计人员必须对他设计的模块应该对哪种变化封闭做出选择。
开闭原则是面向对象设计的核心所在。遵循这个原则可以带来面向对象技术所声称的各种好处,如可维护、可复用、灵活性好等等。但不可以过度抽象,每个地方都抽象。
里氏代换原则
里氏代换原则,即子类型必须能够替换掉他们的父类型。翻译成白话就是一个软件实体如果使用的是一个父类的话,那么一定适用于其子类。也就是说在软件里面把父类都换成他的子类,程序的行为没有变化。
依赖倒转原则
依赖倒转原则,即:A.高层模块不应该依赖低层模块。两个都应该依赖抽象。B:抽象不应该依赖细节,细节应该依赖抽象。用大白话说就是,要针对接口编程,不要针对实现编程。
依赖倒转原则可以说是面向对象设计的标志,如果程序中所有的依赖关系都是终止于抽象类或接口,那就是面向对象的设计,反之就是过程化的设计了。
迪米特法则
迪米特法则,指如果两个类不必直接通信,那么这两个类就不应当发生直接的相互作用。如果其中一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个类。体现到我们的设计上,就是每个类都应该尽量降低成员的访问权限,即强调了低耦合。
2.装饰模式(Decorator Pattern)
解决的问题
装饰模式,动态地给一个对象添加一些额外的职责。当我们需要为程序添加新的功能的时候,我们把每个要装饰的功能放在单独的类中,然后让这个类包装原有的类,这样就可以把类中的装饰功能从类中删除,简化原有的类。也可以去除类中重复的装饰逻辑。
类图结构
在如上的类图中,Component定义了一个对象接口,可以给这些对象动态地添加职责。ConcreteComponent定义了一个具体的对象,也可以给这个对象添加一些职责。Decorator类是装饰抽象类,继承了Component,从外类来拓展Component类的功能。但对于Component来说,无需知道Decorator的存在。ConcreteDecorator就是具体的装饰对象,起到给Component添加职责的功能。
如下基本代码:
Component
类
public abstract class Component{
public abstract void operation();
}
ConcreteComponent
类
public class ConcreteComponent extends Component
{
@Override
public void operation(){
System.out.println("具体对象的操作!");
}
}
Decorator
类
public abstract class Decorator extends Component{
protected Component component;
public void setComponent(Component component){
this.component = component;
}
@Override
public void operation(){
if(component != null){
component.operation();
}
}
}
ConcreteDecoratorA
类
public class ConcreteDecoratorA extends Decortor{
private String addedState;
@Override
public void operation(){
super.operation();
addedState = "New State";
System.out.println("具体装饰对象A的操作");
}
}
优点和缺点
总的来说,装饰模式可以动态的为已有功能添加更多的功能。这些功能多半只满足一些只在特定情况下才会执行的特殊行为的需要。因此,为了减轻主类的负担才有了装饰模式的产生。但使用装饰模式会使得查错变的困难,因为这些对象看上去都很类似。
3.代理模式(Proxy Pattern)
解决的问题
代理模式,可以为其他对象提供一种代理以控制对这个对象的访问。通过代理模式可以详细控制访问某个类或者某个对象的方法,在调用这个方法前做前置处理等等。这也是Spring中的AOP实现的原理。
类图结构
如图所示,Subject类定义了Proxy和RealSubject的共用接口,这样就可以在任何使用RealSubject的地方都可以使用Proxy。RealSubject类代表Proxy所代表的真实实体,Proxy类可以保存一个引用使得代理可以访问实体,并提供一个与Subject的接口相同的接口,这样代理就可以用来替代实体。
代码如下:
Subject
类
public abstract class Subject{
public abstract void request();
}
RealSubject
类
public class RealSubject extends Subject{
@Override
public void request(){
System.out.println("真实的请求");
}
}
Proxy
类
public class Proxy extends Subject{
RealSubject realSubject;
@Override
public void request(){
if(realSubject == null){
realSubject = new RealSubject();
}
realSubject.request();
}
}
优点和缺点
代理模式的应用十分广泛,如远程代理、虚拟代理、安全代理等等。但代理模式会造成系统设计中类的数量增加,且会使得系统的复杂度上升。