这两天项目刚结束,就听说要开始二期迭代开发了,我的天还好在项目设计初期的时候了解了设计模式,项目中用到了几个设计模式,二期还不是简简单单,三下五除二搞完就可以摸鱼了,做个总结,分享一下!!!
单一职责原则
介绍
单一职责原则定义是:应该且仅有一个原因印奇类的变更。也就是一个类只做一件事情
优点
1、降低类的复杂性,实现了什么职责都有清晰的定义; 2、可读性提高; 3、可维护性提高; 4、变更引起风险降低。
代码示例
开发个支付宝,用户登陆后支付退款
public interface AliPay {
public void login(User user);
public void pay(int money);
public void refund(int money);
}
从项目上看这个类是操作支付宝的,它符合单一原则吗?很明显不符合 对接口一定要做到职责单一,类的设计尽量做到只有一个原因引起变话
public interface AliPay {
public void pay(int money);
public void refund(int money);
}
public interface AliPayLogin {
public void login(User user);
}
里氏替换原则
介绍
里氏替换原则定义是:只要父类存在的地方子类就可以替换父类出现,并且不会出现异常,但是反过来就不一定满足
解析
因为代码过程中会经常出现继承关系,所以这是给继承关系施加的一种约束 1、子类必须完全实现父类的方法;不实现继承无意义 2、子类可以有自己的个性;子类可以扩展自己 3、覆盖或者是实现父类的方法时入参可以被放大;子类入参应该是父类入参的父类(你可以把Map传给HashMap,但是不能反过来) 4、覆写或者实现父类方法时输出结果可以被缩小;(父类输出是Map,子类可以HsahMap,但是父类是HsahMap,子类用什么?)
代码示例
开发个支付宝,用户登陆后支付退款
public class AliPay {
public void pay(HashMap money){
System.out.println("父类:普通支付");
}
public Map refund(HashMap money){
System.out.println("父类:退款成功");
return money;
}
}
class SaomaPay extends AliPay{
public void pay(Map money) {
System.out.println("子类:扫码支付");
}
public HashMap refund(Map money) {
System.out.println("子类:操作成功后返回新的Map");
return new HashMap();
}
}
class Client{
public static void main(String[] args) {
System.out.println("父类");
AliPay aliPay = new AliPay();
HashMap hashMap = new HashMap();
aliPay.pay(hashMap);
Map refund = aliPay.refund(hashMap);
System.out.println("子类");
SaomaPay saomaPay = new SaomaPay();
saomaPay.pay(hashMap);
Map refundSaoma = saomaPay.refund(hashMap);
}
}
输出结果
输出结果: 父类 父类:普通支付 父类:退款成功 子类 父类:普通支付 父类:退款成功 可以看到这是正常的
修改子类覆盖的方法入参HashMap后: 父类 父类:普通支付 父类:退款成功 子类 父类:普通支付 子类:操作成功后返回新的Map 子类没有覆写的前提下走到了子类的方法中,这样会引起业务混乱
依赖倒置原则
介绍
依赖倒置原则定义是:模块之间的依赖应该通过抽象联系在一起,而不是依赖于实现类,简而言之就是面向接口编程。
优点
1、减少类之间的耦合; 2、提高了系统的稳定性; 3、降低了并行开发引起的风险; 4、提高了代码可读性和可维护性。
代码示例
开发个支付宝,用户登陆后支付退款
public interface Pay {
public void pay(int money);
public void refund(int money);
}
class WeCatPay implements Pay{
@Override
public void pay(int money) {
System.out.println("你使用了微信支付金额:" + money);
}
@Override
public void refund(int money) {
System.out.println("你使用了微信退款金额:" + money);
}
}
class CreditCardPay implements Pay{
@Override
public void pay(int money) {
System.out.println("你使用了信用卡支付金额:" + money);
}
@Override
public void refund(int money) {
System.out.println("你使用了信用卡退款金额:" + money);
}
}
class ZhangSan{
private Pay pay;
public void setPay(Pay pay){
this.pay = pay;
}
private int money;
public void setMoney(int money){
this.money = money;
}
public void pay() {
pay.pay(money);
}
public void refund() {
pay.refund(money);
}
}
class Client{
public static void main(String[] args) {
ZhangSan zhangSan = new ZhangSan();
zhangSan.setMoney(10);
zhangSan.setPay(new WeCatPay());
zhangSan.pay();
zhangSan.refund();
zhangSan.setPay(new WeCatPay());
zhangSan.pay();
zhangSan.refund();
}
}
输出结果
输出结果: 你使用了微信支付金额:10 你使用了微信退款金额:10 你使用了微信支付金额:10 你使用了微信退款金额:10
接口隔离原则
介绍
接口隔离原则定义是:客户端不应该依赖它不需要的接口,类之间的依赖应该建立在最小的接口上。 简单一句话就是接口要单一,也就是接口或者类中方法尽量少。
优点
1、降低类的复杂性,实现了什么职责都有清晰的定义; 2、可读性提高; 3、可维护性提高; 4、变更引起风险降低。
解析
接口设计不能太小(定义一个员工类,一级证件,二级证件,三级证件,虽然灵活性上去了,但是有的员工没有一级证件,所以要拆分这个类中的接口),不能太大(灵活性太差,过于于臃肿),与单一职责类似,单一职责是业务上的划分,接口隔离是接口上的。
迪米特法则
介绍
迪米特法则定义是:一个类对其他类有最少的了解。简单地说提供一个public方法解决我的问题。
优点
1、减少类之间的耦合; 2、提高系统稳定; 3、降低并行开发风险; 4、提高可读性和可维护性。
解析
一个类暴漏的公共方法越多面临的风险越大。 一个场景中用大一个类中的多个方法,尽量合并。
开闭原则
介绍
开闭原则定义是:一个模块应该对扩展开放对修改关闭。
优点
1、减少类之间的耦合; 2、提高复用性; 3、有较高的维护性; 4、提高可读性和可维护性。
解析
修改关闭并不意味着不修改,一个方法更改对其它模块不产生任何影响。 去扩展一个类好过于直接修改类本身。 设计之初应该多考虑各种情况,确保之后新的需求逻辑顺畅进行
代码示例
原有设计仅仅是商品支付
public interface Pay {
public void pay(Order order);
}
class WeCatPay implements Pay{
@Override
public void pay(Order order) {
System.out.println("支付");
System.out.println(order.getGoodsName() + "价格:" + order.getOrderMoney());
}
}
@Data
class Order{
String goodsName = "《设计模式之禅》";
int orderMoney = 10;
}
class Client{
public static void main(String[] args) {
Pay pay = new WeCatPay();
pay.pay(new Order());
}
}
输出结果
结果: 支付 《设计模式之禅》价格:10
扩展示例
新的需求,商品支付要有优惠 怎么办? 最简单修改Order类中getOrderMoney()方法打个折就行 但是这个类被多个场景使用呢?比如采购,再比如对账。他们要看到原价,所以不可以在原Order属性中修改
public interface Pay {
public void pay(Order order);
}
class WeCatPay implements Pay{
@Override
public void pay(Order order) {
System.out.println("支付");
System.out.println(order.getGoodsName() + "价格:" + order.getOrderMoney());
}
}
@Data
class Order{
String goodsName = "《设计模式之禅》";
int orderMoney = 10;
}
class DiscountOrder extends Order{
int discountMoney = 1;
@Override
public int getOrderMoney() {
return super.getOrderMoney() - this.discountMoney;
}
}
class Client{
public static void main(String[] args) {
Pay pay = new WeCatPay();
pay.pay(new DiscountOrder());
}
}
输出结果
结果: 支付 《设计模式之禅》价格:9
|