10-设计模式与设计原则

本文详细介绍了面向对象设计的七大原则,包括开闭原则、里氏代换原则、依赖倒置原则、组合复用原则、接口隔离原则、迪米特法则和单一职责原则。此外,还探讨了设计模式的重要性,列举了工厂方法、抽象工厂、单例模式、桥模式、装饰者模式、适配器模式、观察者模式、责任链模式、策略模式和代理模式的定义、应用场景和优缺点。通过这些设计原则和模式,可以更好地实现代码复用、提高系统的可维护性和灵活性。
摘要由CSDN通过智能技术生成

做到OOD的代码需要满足的条件:

  • 面向对象
  • 复用
  • 能以最小的代价满足变化
  • 不用改变现有代码满足扩展

面向对象设计原则

开闭原则OCP

Open-Closed Principle

开闭原则是指:软件组成实体应该是对扩展开放的,但是对修改关闭的。

实现开闭原则关键在于——抽象化
可以给系统定义一个不在更改的抽象设计,允许无尽的行为在实现层被实现。抽象层预测所有可能扩展。

一个软件系统的所有模块不可能都满足OCP,但是应该努力最小化这些不满足OCP的模块数量

----------销售打折问题:

//零件类
class Part {
   
	protected double basePrice;
	private PricePolicy pricePolicy;
	public void setPricePolicy(PricePolicy policy) {
   
   	 	 pricePolicy = policy;
	}
	public void setPrice(double price) {
   
  	   basePrice = price;
	}
	public double getPrice() {
   
    	  if (pricePolicy == null)
     		   return basePrice;
    	  else
    		    return pricePolicy.getPrice(basePrice);
	}
}
//内存、磁盘继承零件
class Memory extends Part{
   }
class Disk extends Part{
   }

//价格政策——原价
class PricePolicy{
   
	public double getPrice(double basePrice){
   
		return basePrice;
	}
}
//促销——原价基础上打折
class Sale extends PricePolicy{
   
	private double discount;
	public void setDiscount(double discount){
   
		this.discount = discount;
	}
	public void double getPrice(double basePrice){
   
		return basePrice * discount;
	}
}

//测试类
public class TestOCP {
   
	public static void main(String[] args) {
   

	  Part p1 = new Memory();
	  p1.setPrice(599);
	  Part p2 = new Disk();
 	  p2.setPrice(499);
  	  Sale sale = new Sale();
  	  sale.setDiscount(0.75);
  	  //磁盘打折
 	  p2.setPricePolicy(sale);
 	  Part[] com = {
    p1, p2 };
 	  System.out.println(totalprice(com));
}

----------画图形问题:

//编写一个shape抽象类
//这个类仅有一个抽象方法draw()
//所有形状都从这个类派生
//当绘制一种新的形状,只需要增加一个新的shape类的派生类。而DrawAllShapes 函数并不需要改变。
abstract class Shape {
   
	abstract void draw();
}

class Circle extends Shape {
   
	void draw() {
   
		System.out.println("I am drawing a circle!");
	}
}
class Square extends Shape {
   
	void draw() {
   
		System.out.println("I am drawing a square!");
	}
}

public class TestOCP2 {
   
	public static void main(String[] args) {
   
		List<Shape> shapeList=new ArrayList<Shape>();
        Circle c=new Circle();
        Square s=new Square();
        shapeList.add(c);
        shapeList.add(s);
        DrawAllShape drawAllShape=new DrawAllShape();
        drawAllShape.drawAllShapes(shapeList);
	}
}

class DrawAllShape {
   
	void drawAllShapes(List<Shape> shapeList) {
   
		for (int i=0;i<shapeList.size();i++)
	// 通过for循环取出list中每个//shape
	{
   
		Shape shape= (Shape)shapeList.get(i);
		shape.draw();}
	}
}

里氏代换原则LSP

Liskov Substitution Principle

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

更通俗的定义:子类可以扩展父类的功能,但不能改变父类原有的功能。

一个软件如果使用的是一个父类的话,如果把该父类换成子类,它不能察觉出父类对象和子类对象的区别

凡是父类适用的地方子类也适用
继承只有满足里氏代换原则才是合理的。

如果两个具体的类A,B之间的关系违反了LSP的设计,(假设是从B到A的继承关系),那么根据具体的情况可以在下面的两种重构方案中选择一种。

  • 创建一个新的抽象类C,作为两个具体类的超类,将A,B的共同行为移动到C中来解决问题。
  • 从B到A的继承关系改为委派关系。

在这里插入图片描述在这里插入图片描述

依赖倒置原则DIP

dependency inversion principle

依赖倒置原则指——

  1. 高层模块不应该依赖于低层模块,二者应该依赖其抽象
  2. 抽象不应该依赖于细节,细节应该依赖抽象
    这里的抽象一般指 抽象类与接口,两者都是不能够实例化的, 细节指实现接口或继承抽象类所产生的类,可以通过new实例化。

依赖倒置原则的本质就是通过抽象使各个类或模块的实现彼此独立,不相互影响,实现模块间的松耦合
这个原则也是OO设计原则中最难以实现的了,如果没有实现这个原则,那么也就意味着开闭原则也无法实现。

常见应用:AGP插槽;驾照;电源插座。

设计模式中最能体现DIP原则的是——抽象工厂模式,工厂和产品都是抽象的。

如何遵循依赖倒置原则:

  1. 通过构造函数传递依赖对象(参数是抽象类或接口)
  2. 通过setter方法传递依赖对象(参数为抽象类或接口)
  3. 接口声明实现依赖对象(参数为抽象类或接口)
//通过构造函数传递依赖对象
public interface IDriver {
   
      public void drive();
}

public class Driver implements IDriver{
   
      private ICar car;
	//构造函数注入
      public Driver(ICar _car){
   
          this.car = _car;
      }
      
      public void drive(){
   
            this.car.run();
      }
 }
//通过setter方法传递依赖对象
public interface IDriver {
   
	//车辆型号
  public void setCar(ICar car);
  public void drive();
}

public class Driver implements IDriver{
   
    private ICar car;
    //setter依赖注入
    public void setCar(ICar car){
   
        this.car = car;
    }
   	public void drive(){
   
   		 this.car.run();
	}
}

public interface ICar {
   
	public void run();
 }
 
public class Benz implements ICar{
   
	public void run(){
   
	System.out.println("奔驰汽车开始运行...");
    }
}

public class Client {
   
       public static void main(..) {
   
        IDriver zhangSan = new Driver();
        ICar benz = new Benz();
        zhangsan.setCar(benz);}
}
//接口声明实现依赖对象
public interface ICar {
   
	public void run();
 }
public class Benz implements ICar{
   
	public void run(){
   
	System.out.println("奔驰汽车开始运行...");
    }
}

public interface IDriver {
   
     public void drive(ICar car);
}
public class Driver imp
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

边懵懵'.ㅅ'

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值