面向对象设计之开闭原则

开闭原则(Open Close Principle)

  1. 开闭原则的定义:
    一个软件实体如类、模块或函数应该对扩展开放,而对修改关闭
  2. 基本概念
  • 开:面向扩展开放
  • 闭:面向修改关闭
    开闭原则其实就是让我们遵循一种编码习惯,尽量通过扩展软件实体的行为来实现对软件的改进变化,而不是通过修改现有的代码来完成这种功能。
  1. 优点
    遵循开闭原则的系统,要有更好的灵活性、可复用性,维护起来也更加方便。
  2. 例子:以商品为例进行开闭原则的说明
public interface Product {
	/**
	 * 获取商品名称
	 * @return
	 */
	String getName();
	
	/**
	 * 获取商品价格
	 * @return
	 */
	Double getPrice();
	
	/**
	 * 获取商品类型
	 * @return
	 */
	Integer getType();
}

public class AProduct implements Product{

	/**
	 * 商品名称
	 */
	private String name;
	
	/**
	 * 商品价格
	 */
	private Double price;
	
	/**
	 * 商品类型
	 */
	private Integer type;
	
	
	/**
	 * @param name
	 * @param price
	 * @param type
	 */
	public AProduct(String name, Double price, Integer type) {
		super();
		this.name = name;
		this.price = price;
		this.type = type;
	}

	@Override
	public String getName() {
		// TODO Auto-generated method stub
		return name;
	}

	@Override
	public Double getPrice() {
		// TODO Auto-generated method stub
		return price;
	}

	@Override
	public Integer getType() {
		// TODO Auto-generated method stub
		return type;
	}

	public static void main(String[] args) {
		AProduct aProduct=new AProduct("笔记本", 9999.9, 1);
		System.out.println("商品名称:"+aProduct.getName()+"\n"
							+"商品价格:"+aProduct.getPrice()+"\n"
							+"商品分类:"+aProduct.getType());
	}
}
商品正常销售,但遇到节假日需要做一些促销活动来吸引更多的购买者。
如对商品进行打折活动。那么问题来了,打折这一动作,对应到代码中就是编码的变化,
我们要做的就是如何调整或者扩展代码来解决问题,一般来说,要做如下动作:

1. 修改接口

  • 在上边的商品接口中添加一个商品打折的方法getDiscountPrice(),来获取打折之后的商品价格。
    如果采用这种方法,就会产生如下问题:

    • Product接口不应该经常被修改,否则接口作为一种契约也就失去了其作用
    • 并非所用的商品都打折,加入其它的实现类之后,也都会实现此接口,但是只有部分商品打折,与我们的实际需求不吻合。

    所以不采用这种方法。

2. 修改接口实现类

  • 直接修改实现类中的getPrice()方法,会导致获取商品的原价格出问题;或添加获取打折的接口,会导致获取价格上存在二义性。
    所以这种方法也不采用。

3.通过扩展来实现新增需求

  • 直接添加一个子类DiscountProduct,重写getPrice()方法,这个方案对原来代码没有任何影响,完全符合开闭原则,所以此方案可行。代码如下:
public class DiscountProduct extends AProduct{

	/**
	 * @param name
	 * @param price
	 * @param type
	 */
	public DiscountProduct(String name, Double price, Integer type) {
		super(name, price, type);
	}
	
	@Override
	public Double getPrice() {
		return super.getPrice()*0.79;
	}
	
	public static void main(String[] args) {
			DiscountProduct discountProduct=new DiscountProduct("HAIER", 999.9,0);
			System.out.println("商品名称:"+discountProduct.getName()
							+"\n商品价格:"+discountProduct.getPrice()
							+"\n商品类型:"+discountProduct.getType());
	}

}

经过上述分析,采用第三种方式,即开闭原则,若是添加其他商品后,价格的变化都可以采用此种方案来解决,不仅对原生代码没有污染,而且现有代码的维护性和灵活度也相当好。

你可能感兴趣的:(面向对象设计之开闭原则)