设计模式(java)———七大原则

目录

设计模式的目的

七大原则:

(1)单一原则

单一职责注意事项和细节

(2)接口隔离原则

(3)依赖倒转原则

依赖倒转原则的注意事项和细节:

(4)里氏替换原则

(5)开闭原则

(6)迪米特法则

注意细节

(7)合成复用原则


设计模式的目的

编写软件的过程中,程序员面临着来自耦合性,内聚性,可扩展性,维护性,灵活性。

  • 代码重用性:相同的代码不用重写
  • 可读性:便于阅读和理解
  • 可扩展性:当扩展其他功能的时候方便
  • 可靠性:添加新功能时对其他的功能没有影响
  • 程序呈现高内聚低耦合的特性

七大原则:

  • 单一原则
  • 接口原则
  • 依赖倒转原则
  • 里氏替换原则
  • 开闭原则
  • 迪米特原则
  • 合成复用原则

(1)单一原则

介绍:对类来说,一个类只应该负责一个职责。

实例:

package com.kun.principle.singlersponsibilit;

public class SingleResponsibility1 {
	public static void main(String[] args) {
		/*
		 * 一个类(违反了单一原则)——》
		 * 三个类(使用了单一原则,但是消耗资源)——》
		 * 一个类三个方法(类上没有体现单一原则,但是方法体现了)
		 * */
		AirVehicle vehicle1=new AirVehicle();
		vehicle1.run("feiji");
		RoadVehicle vehicle2=new RoadVehicle();
		vehicle2.run("qiche");
		WaterVehicle vehicle3=new WaterVehicle();
		vehicle3.run("zixingche");
	}
}
// 交通工具类
class AirVehicle{
	public void run(String vehicle) {
		System.out.println(vehicle + " zai fei");
	}
}
class RoadVehicle{
	public void run(String vehicle) {
		System.out.println(vehicle + " zai pao");
	}
}
class WaterVehicle{
	public void run(String vehicle) {
		System.out.println(vehicle + " zai you");
	}
}

单一职责注意事项和细节

  • 降低类的复杂度,一个类只负责一项职责。
  • 提高类的可读性,可维护性。
  • 降低变更引起的风险。
  • 通常情况下,我们应当遵守单一职责原则,除非逻辑足够简单。可以在方法上实现单一职责。

(2)接口隔离原则

介绍:一个类对另一个类的依赖,用接口来依赖,应当依赖最小组合的接口。如(A用B中的1,2,3接口,则应该拆分[1],[2,3])

实例:

package com.kun.principle.segregation;

public class Segregation {
	public static void main(String[] args) {
		A a=new A();
		a.depend1(new B());
	}
}
interface Interface1{
	void operation1();
	void operation2();
	void operation3();
	void operation4();
	void operation5();
}
class B implements Interface1{
	@Override
	public void operation1() {
		System.out.println("B 1");
	}
	@Override
	public void operation2() {
		System.out.println("B 2");
	}
	@Override
	public void operation3() {
		System.out.println("B 3");
	}
	@Override
	public void operation4() {
		System.out.println("B 4");
	}
	@Override
	public void operation5() {
		System.out.println("B 5");
	}
}
class A {
	public void depend1(Interface1 i) {
		i.operation1();
		i.operation2();
		i.operation3();
	}
}

改进版

package com.kun.principle.segregation;

public class improve {
	public static void main(String[] args) {
	}
}
interface inter1{
	void operation1();
}
interface inter2{
	void operation2();
	void operation3();
}
class B implements inter1,inter2{
	@Override
	public void operation1() {
		System.out.println("B 1");
	}
	@Override
	public void operation2() {
		System.out.println("B 2");
	}
	@Override
	public void operation3() {
		System.out.println("B 3");
	}
}
class A {
	public void depend1(inter1 i) {
		i.operation1();
	}
	public void depend2(inter2 i) {
		i.operation2();
		i.operation3();
	}
}


(3)依赖倒转原则

介绍:

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

实例:

package com.kun.principle.inversion;

public class DependecyInversion {
	public static void main(String[] args) {
		//客户端无需改变
		Person person =new Person();
		person.receive(new Email());
		person.receive(new WeiXin());
	}
}
interface IReceive{
	public String getInfo();
}
class Email implements IReceive{
	public String getInfo() {
		return "hello";
	}
}
class WeiXin implements IReceive{
	@Override
	public String getInfo() {
		return "weixin ok";
	}
}
//方式一:简单,但是如果对象增加,相应的方法也要增加。
//		解决:所以要引入接口,对接口产生依赖
//class Person{
//	public void receive(Email email) {
//		System.out.println(email.getInfo());
//	}
//}
//方法二
class Person{
	public void receive(IReceive iReceive) {
		System.out.println(iReceive.getInfo());
	}
}

依赖倒转原则的注意事项和细节:

  1. 低层模块尽量都要有抽象类和接口
  2. 变量的声明类型尽量是抽象类或接口
  3. 继承时遵循里氏替换原则

(4)里氏替换原则

介绍:

  • 我们引用基类的地方必须能透明的使用其子类的对象
  • 在使用继承时,在子类中尽量不要重写父类的方法
  • 继承让两个类的耦合性增强了,在适当的情况下可以使用聚合,组合,依赖

实例:

package com.kun.principle.liskov;

public class Liskov {
	public static void main(String[] args) {
		A a =new A();
		System.out.println("11-3="+a.fun1(11, 3));
		System.out.println("1-3="+a.fun1(1, 3));
		B b=new B();
		System.out.println("11+3="+b.fun1(11, 3));
		System.out.println("1+3="+b.fun1(1, 3));
		System.out.println("11+3+9="+b.fun2(11, 3));
		System.out.println("11-3="+b.fun3(11, 3));
	}
}
//解决方法
class Base{
	
}
class A extends Base{
	public int fun1(int num1,int num2) {
		return num1-num2;
	}
}
class B extends Base{
	private A a=new A();
	public int fun1(int a, int b) {
		return a+b;
	}
	public int fun2(int a,int b) {
		return fun1(a, b)+9;
	}
	public int fun3(int a,int b) {
		return this.a.fun1(a, b);
	}
}
//之前代码,违背里氏替换原则
//class A{
//	public int fun1(int num1,int num2) {
//		return num1-num2;
//	}
//}
//class B extends A{
//	public int fun1(int a, int b) {
//		return a+b;
//	}
//	public int fun2(int a,int b) {
//		return fun1(a, b)+9;
//	}
//}

(5)开闭原则

介绍:

  • 对一个软件实体,模块和函数应该扩展开放,对修改关闭。
  • 用抽象构建框架,用实现扩展细节
  • 通过扩展软件实体的行为来变化,而不是修改
  • 编程中遵循各个原则,各个原则都遵循开闭原则。

实例:改进前

//缺点:增加一个其他图形类,要创建一个类,然后在GraphicEditor添加判断,添加方法,修改代码太多
public class Ocp {
	public static void main(String[] args) {
		GraphicEditor graphicEditor=new GraphicEditor();
		graphicEditor.drawShape(new Rectangle());
		graphicEditor.drawShape(new Circle());
	}
}
class GraphicEditor{
	public void drawShape(Shape s) {
		if (s.m_type==1) {
			drawRectangle(s);
		}else if (s.m_type==2) {
			drawClircle(s);
		}
	}
	public void drawRectangle(Shape r) {
		System.out.println("ju xing");
	}
	public void drawClircle(Shape r) {
		System.out.println("yuan");
	}
}
class Shape{
	int m_type;
}
class Rectangle extends Shape{
	Rectangle(){
		super.m_type=1;
	}
}
class Circle extends Shape{
	Circle(){
		super.m_type=2;
	}
}

改进后的代码:

package com.kun.principle.ocp;

public class Ocp {
	public static void main(String[] args) {
		GraphicEditor graphicEditor=new GraphicEditor();
		graphicEditor.drawShape(new Rectangle());
		graphicEditor.drawShape(new Circle());
	}
}
class GraphicEditor{
	public void drawShape(Shape s) {
		s.draw();
	}
}
abstract class Shape{
	public abstract void draw();
}
class Rectangle extends Shape{
	@Override
	public void draw() {
		System.out.println("ju xing");
	}
}
class Circle extends Shape{
	@Override
	public void draw() {
		System.out.println("yuan");
	}
}

(6)迪米特法则

介绍:

  • 一个对象应该对其他对象保持最少的了解
  • 类和类关系越密切。耦合度越大。
  • 迪米特法则又叫最少知道法则,即一个类对自己依赖的类知道的越少越好。也就是说,对于被依赖的类尽量把自己封装起来,只提供public方法。
  • 迪米特定义:只和直接朋友通信

实例:

        创建一个对象

        遍历输出对象

分析:

        SchoolManager的直接朋友类Employee

class SchoolManager
//返回学枚总部的员工
public List<Employee>getAllEmployee(){
    List<Employee>list new ArrayList<Employee>();
    for(inti=0;i<5;i++){//这里我们增加了5个员工到1ist
        Employee emp new Employee();
        emp.setId("学校总部员工id="+i);
        list.add(emp);
    }
       return list;
}

注意细节

  • 迪米特法则的核心是降低类之间的耦合
  • 但是注意:由于每个类都减少了不必要的依赖,因此迪米特法则只是要求降低耦合

(7)合成复用原则

介绍:

  • 尽量使用合成和聚合的方式,而不是使用继承。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值