【设计模式】七大原则

一、单一职责原则

定义:
一个类只负责一项职责。

优点:
①降低类的复杂度;②提高代码可读性;③提高代码可维护性。

违反条件:
①类中方法足够少,可以仅在方法级别遵循改原则;
②方法逻辑足够简单,可以在方法级别违反该原则。

二、接口隔离原则

定义:
客户端不应该依赖它不需要的接口(即接口中含有不需要实现的方法)。一个类对另一个类的依赖应该建立在最小的接口上。

钩子方法:
钩子的实现方法是对于抽象方法或者接口中定义的方法的一个空实现。
比如说有一个接口有7个方法,而你只想用其中一个方法,那么你可以写一个抽象类实现这个接口,在这个抽象类里将你要用的那个方法设置为abstract,其它方法进行空实现,然后再继承这个抽象类,就不需要实现其它不用的方法。

//动物接口
public interface IAnimal{
	void eat();
	void fly();
	void run();
}

//陆地动物不需要实现fly()这个方法
public abstract class TerrestrialAnimal implements IAnimal{
	@Override
	abstract void eat();

	@Override
	void fly(){
		//什么也不做
	};

	@Override
	abstract void run();
}

//陆生动物实例
public class Dog extends TerrestrialAnimal{

	@Override
	void eat(){
		System.out.println("吃");
	}

	@Override
	void run(){
		System.out.println("跑");
	}
}

三、依赖倒置原则

定义:
① 高层模块不应该依赖底层模块,二者都应该依赖抽象。
② 抽象不应该依赖细节,细节应该依赖抽象。
③ 依赖倒置的中心思想是 面向接口编程
④ 依赖倒置原则是基于这样的设计理念:
 – 相对于细节的多变性,抽象的东西要稳定的多。
 – 以抽象为基础搭建的架构比以细节为基础搭建的架构要稳定的多。
⑤使用接口或抽象类的目的是指定好规范,而不涉及任何具体的操作,把展现细节的任务交给他们的实现类来完成。

依赖关系传递方式:
1.接口传递

//开关
interface IOpenClose{
    public void open(ITv tv);
}
//电视机
interface ITv{
    public void play();
}
//开关实现类(无需关注play方法的实现)
class IOpenCloseImpl implements IOpenClose{
    @Override
    public void open(ITv tv) {
        tv.play();
    }
}

2.构造方法传递

interface IOpenClose{
    public void open();
}
 
interface Itv{
    public void play();
}
 
class IOpenCloseImpl implements IOpenClose{
    public Itv tv;
    public IOpenCloseImpl(Itv tv){
        this.tv = tv;
    }
    @Override
    public void open() {
        this.tv.play();
    }
}

3.setter传递

interface IOpenClose{
    public void open();
    public void setItv(Itv tv);
}
 
interface Itv{
    public void play();
}
 
class IOpenCloseImpl implements IOpenClose{
    private Itv tv;
 
    @Override
    public void setItv(Itv tv) {
        this.tv = tv;
    }
 
    @Override
    public void open() {
        this.tv.play();
    }
 
}

注意事项及细节:
1.低层模块尽量有接口或者抽象类;
2.变量的声明尽量是抽象类或接口,有利于程序的扩展和优化;
3.继承时需遵循里氏替换原则

四、里氏替换原则

定义:
所有引用基类(父类)的地方必须能透明地使用其子类对象。

通俗概念:
子类可以扩展父类的功能,单不能修改父类原有的功能。包含以下4层含义:

①子类可以实现父类的抽象方法,但不能覆盖(重写)父类的非抽象方法;
②子类可以增加增加特有的方法;
③子类重载父类的方法时,方法的前置条件(方法形参)要比父类输入的参数更宽松;
④子类实现父类的抽象方法时,方法的后置条件(返回值)要比父类更严格。

优点:
解决继承中的可能产生的问题。

继承的缺点:
子类重写父类方法,可能造成原有功能出现错误;

解决方法:
①去掉原来的父类和子类的继承关系,让它们都继承一个更通俗的基类,用依赖、聚合、组合等关系替代;
②使用 final 关键字修饰父类中不希望被子类重写的方法。

五、开闭原则

定义:
① 一个软件实体,如类、模块和函数应该对扩展开放,对修改关闭。
②一个软件实体应该通过扩展来实现变化。而不是通过修改已有的代码来实现变化。

通俗概念:
对扩展开发,对修改关闭。

优点:
避免修改原有代码而造成原要正常工作的代码出现故障。

六、迪米特法则

定义:
①一个对象应该对其他对象有最少的了解,所以迪米特法则又叫做 最少知识原则
②类与类关系越密切,耦合度越大。
③对于被依赖的类不管多么复杂,都尽量将逻辑封装在类的内部。对外除了提供public方法,不泄露任何信息。
④只与 直接朋友 通信。

优点:
降低类之间的耦合。每个对象尽量减少对其他对象的了解,使得系统的功能模块功能独立,相互之间不存在(或很少有)依赖关系。

直接朋友:
只要两个对象之间耦合(依赖、关联、组合、聚合),这两个对象就是朋友关系。其中,出现 成员变量方法参数方法返回值 中的类为直接朋友。
出现在局部变量中的类不是直接朋友。
陌生的类最好不要以局部变量的形式出现在类的内部。

七、合成复用原则

定义:
尽量使用合成 / 聚合的方式,而不是继承。

问题来源:
继承复用的缺点:
在这里插入图片描述
① 继承复用破坏包装。
继承将父类的实现细节暴露给了子类,父类的内部细节常常对子类是透明的,因此这种复用是透明的复用,又叫 白箱 复用。
② 如果父类的实现改变了,那么子类的实现也不得不发生改变。因此,当一个父类发生了改变时,这种改变会传导到一级又一级的子类,使得设计师不得不相应的改变这些子类,以适应超类的变化。
③ 从父类继承而来的实现是静态的,不可能在运行时间内发生变化,因此没有足够的灵活性。

优点:
在这里插入图片描述
①它维持了类的封装性。
成分对象的内部细节是新对象看不见的,所以这种复用又称为 黑箱 复用。
②新旧类之间的耦合度低。
这种复用所需的依赖较少,新对象存取成分对象的唯一方法是通过成分对象的接口。
③复用的灵活性高。
这种复用可以在运行时动态进行,新对象可以动态地引用与成分对象类型相同的对象。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章