六大设计原则
定义
类、模块、函数等等等应该是可以拓展的,但是不可修改。
白话点来说就是,拓展延伸可以,但是你不可以修改我。
示例
此处以售卖楼盘为例
定义房产信息
import java.math.BigDecimal;
public interface IHouse {
String getAddress();
String getArea();
String getSchool();
BigDecimal getPrice();
}
房产信息包含了地址,面积,学区房以及房价
定义实现类
import com.design.principle.openclosed.IHouse;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
@Service
public class HouseImpl implements IHouse {
private String address;
private String area;
private String school;
private BigDecimal price;
public HouseImpl(String address, String area, String school, BigDecimal price) {
this.address = address;
this.area = area;
this.school = school;
this.price = price;
}
@Override
public String getAddress() {
return address;
}
@Override
public String getArea() {
return area;
}
@Override
public String getSchool() {
return school;
}
@Override
public BigDecimal getPrice() {
return price;
}
}
定义一个售楼处
import com.design.principle.openclosed.IHouse;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
public class SalesOffice {
private final static List<IHouse> houseList = new ArrayList<>();
static {
houseList.add(new HouseImpl("淮海路100弄世界花苑1栋一单元201室", "100m^2", "实验小学", new BigDecimal(1000000)));
houseList.add(new HouseImpl("淮海路100弄世界花苑1栋一单元202室", "102m^2", "实验小学", new BigDecimal(1150000)));
houseList.add(new HouseImpl("淮海路100弄世界花苑3栋二单元203室", "100m^2", "实验小学", new BigDecimal(1100000)));
houseList.add(new HouseImpl("淮海路100弄世界花苑3栋二单元204室", "110m^2", "实验小学", new BigDecimal(1200000)));
houseList.add(new HouseImpl("东海路300弄龙庭花苑2栋一单元501室", "150m^2", "东海小学", new BigDecimal(1700000)));
}
public static void main(String[] args) {
for (IHouse house : houseList) {
System.out.println("卖出房源->地址:" + house.getAddress() + ";面积:" + house.getArea() + ";学区:" + house.getSchool() + ";房价:" + house.getPrice());
}
}
}
此时可以正常售卖房产
新需求
因为房地产行业进入冷冬,集团准备开展活动,对满足条件的房产进行优惠售卖。以上的项目是无法满足需求的,所以需要对该项目进行改造。
方案一:修改接口
修改IHouse
,添加 getDiscounts()方法,然后对应的去修改实现类,在售楼处通过实际价格 getPrice() 减去优惠价格 getDiscounts() 得到售楼价,但是在此处就会发现,修改的接口,就需要对应的去修改实现类HouseImpl
和售楼处SalesOffice
,不推荐。
代码:
import java.math.BigDecimal;
public interface IHouse {
String getAddress();
String getArea();
String getSchool();
BigDecimal getPrice();
BigDecimal getDiscounts();
}
import com.design.principle.openclosed.IHouse;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
@Service
public class HouseImpl implements IHouse {
private String address;
private String area;
private String school;
private BigDecimal price;
private BigDecimal discount;
public HouseImpl(String address, String area, String school, BigDecimal price, BigDecimal discount) {
this.address = address;
this.area = area;
this.school = school;
this.price = price;
this.discount = discount;
}
@Override
public String getAddress() {
return address;
}
@Override
public String getArea() {
return area;
}
@Override
public String getSchool() {
return school;
}
@Override
public BigDecimal getPrice() {
return price;
}
@Override
public BigDecimal getDiscounts() {
return discount;
}
}
import com.design.principle.openclosed.IHouse;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
public class SalesOffice {
private final static List<IHouse> houseList = new ArrayList<>();
static {
houseList.add(new HouseImpl("淮海路100弄世界花苑1栋一单元201室", "100m^2", "实验小学", new BigDecimal(1000000), new BigDecimal(1000)));
houseList.add(new HouseImpl("淮海路100弄世界花苑1栋一单元202室", "102m^2", "实验小学", new BigDecimal(1150000), new BigDecimal(2100)));
houseList.add(new HouseImpl("淮海路100弄世界花苑3栋二单元203室", "100m^2", "实验小学", new BigDecimal(1100000), new BigDecimal(3000)));
houseList.add(new HouseImpl("淮海路100弄世界花苑3栋二单元204室", "110m^2", "实验小学", new BigDecimal(1200000), new BigDecimal(2000)));
houseList.add(new HouseImpl("东海路300弄龙庭花苑2栋一单元501室", "150m^2", "东海小学", new BigDecimal(1700000), new BigDecimal(5000)));
}
public static void main(String[] args) {
for (IHouse house : houseList) {
System.out.println("卖出房源->地址:" + house.getAddress() + ";面积:" + house.getArea() + ";学区:" + house.getSchool() + ";房价:" + house.getPrice().subtract(house.getDiscounts()));
}
}
}
方案二:修改实现类
在实现类出定义一个 getDiscounts(), 在 getPrice()方法里计算优惠后的价格, 但是这里存在一个问题, getPrice()得到的价格是优惠后的价格,那么销售人员或者购买人员无法知道房产的原价和优惠价格了。
代码
@Override
public BigDecimal getPrice() {
return price.subtract(getDiscounts());
}
private BigDecimal getDiscounts() {
return discount;
}
方案三:添加扩展类
添加子类活动价实现类 ActivityPriceImpl
继承 HouseImpl
, 重写getPrice()方法, 这样就不会修改原来的实现类,改动少,风险也小。
代码
import java.math.BigDecimal;
public class ActivityPriceImpl extends HouseImpl {
public ActivityPriceImpl(String address, String area, String school, BigDecimal price) {
super(address, area, school, price);
}
@Override
public BigDecimal getPrice() {
BigDecimal price = super.getPrice();
// 所有房产优惠1000
return price.subtract(new BigDecimal(1000));
}
}
优点
1)降低耦合性。
2)适应性,灵活性,稳定性比较良好。
3)开闭原则是最基础的一个原则,前面介绍的5个原则都是开闭原则的具体形态,而开闭原则才是其精神领袖。