常用设计模式

常用设计模式

这篇文章主要是浅谈常用的一些设计模式
1、我们为什么要用设计模式?
业务是变更的,所以需求也是变更的。做软件开发,不变的是变化;这是真理,就像在java中为什么会有interface接口一样。它的存在就是为了隔离变化。使用设计模式也是一样,对我们的代码进行抽象隔离,使代码变得易扩展,易维护。尽量做到需求变更时,我们能少改代码,甚至不改代码。本文章就简单介绍策略模式,工厂模式的结合使用。

策略模式

这基本上是最常用的设计模式之1
有一个经典的场景:双11 、 618 这种促销活动,各种商品有不同的促销活动。什么满减,每满减,数量折扣 2件7折,3件5折 满3件免最低一件等等 这些活动琳琅满目。
后台代码如何实现对应订单的金额计算?一个活动对应的就是一个完整计算订单金额的算法。下面是传统的写法

//计算订单金额的方法,接受一个订单,和一个活动名称,两个参数
public BigDecimal preOrder(Order order,String promotion){
	switch(promotion){
	case "promotion1":
		//活动1订单金额算法
		return  calPromotion1(order);
	case "promotion2":
	   //活动2订单金额算法
	   return  calPromotion2(order);
	case "promotion3":
	   //活动3订单金额算法
	   return  calPromotion3(order);
	...
	}
}

这样写固然能实现业务,但是随着活动的增加,这个类的代码会变得无比臃肿、而且我们要实现无数个calPromotion方法,最后代码爆炸难以维护。
这时候我们就可以采用策略模式,定义一个接口,这个接口只有一个计算订单金额的方法:

//计算订单金额的接口
public interface PromotionCalculation{
	//计算订单金额的方法
	public BigDecimal calculation(Order order);
}
//活动1的订单金额计算方法实现
public class PromotionCalculation1 implements PromotionCalculation{
	//计算订单金额的方法
	public BigDecimal calculation(Order order){
		//具体算法
		return orderPrice;
	}
}

这样我们就完成了根据活动计算订单金额这个行为的抽象,每个一个具体的活动就只需要实现这个接口,在上面的switch里面,我们只需要new PromotionCalculation1对象就能调用对应活动的计算方法。避免了再service类里面写无数个calPromotion方法,避免了类爆炸。service层代码变成了这样

public BigDecimal preOrder(Order order,String promotion){
	switch(promotion){
	case "promotion1":
		//活动1订单金额算法
		return new PromotionCalculation1().calculation(order);
	case "promotion2":
	   //活动2订单金额算法
	   return new PromotionCalculation2().calculation(order);
	case "promotion3":
	   //活动3订单金额算法
	   return  new PromotionCalculation3().calculation(order);
	...
	}
}

工厂模式

还是上面的场景,虽然避免service里面不会再有N个 calPromotion方法,但还是避免不了随着活动的增多,switch里面的代码还是会无限扩展。
这个时候工厂模式就有了用武之地。在次改造代码;工厂工厂,就是生产产品。我们创建的一个工厂类,里面还是只有一个方法,就是创建具体实现订单金额计算接口的实现类对象createPromotionCalculationInstance(),

public class PromotionCalculationFactory{
	//创建具体 根据活动计算订单金额实现类的实例
	PromotionCalculation createPromotionCalculationInstance(String promotion){
			switch(promotion){
			case "promotion1":
				//活动1订单金额算法实现类的实例
			   return  new  PromotionCalculation1();
			case "promotion2":
			   //活动2订单金额算法实现类的实例
			   return  new  PromotionCalculation2();
			case "promotion3":
	   			//活动3订单金额算法实现类的实例
	   		   return  new  PromotionCalculation3();
	...
	}
  }
}

有了上面的工厂,我们的service类里面就变得简单了

public BigDecimal preOrder(Order order,String promotion){
	//根据活动创建 根据活动计算订单金额的具体实现类对象 并调用计算订单金额的方法。
	return new PromotionCalculationFactory()
	.createPromotionCalculationInstance(promotion)
	.calculation(order);
}

到了这里,我们service里面的代码似乎就变得很简洁,就一行就搞定了。再思考,现在还有一个问题,就是工厂类里面,随着活动的增加switch里的代码还是会变得臃肿,这时候我们可以利用数据库来实现。
1、创建一张数据库表,里面存的是一个个活动信息,并将实现类的资源路径作为字段保存起来。类似这种:

idpathname
1com.service.PromotionCalculation1活动1
2com.service.PromotionCalculation2活动2

然后在工厂里面,根据前端传过来promotion字段去数据库查询对应活动信息。再根据资源路径动态的创建实例,工厂改造过后的代码:

public class PromotionCalculationFactory{
	//活动信息dao层
	private PromotionDao promotionDao;
	//创建具体 根据活动计算订单金额实现类的实例
	PromotionCalculation createPromotionCalculationInstance(String promotion){
			//根据promotion查询数据库对应的活动信息
			PromotionEntity promo = PromotionDao.selectByPromotion(promotion);
			//获取活动实现类path
			String path = promo.getPath();
			//加载类对象
			Class cls = Class.forName(path);
			//创建实例并返回
			return (PromotionCalculation) cls.newInstance();
  }
}

这样我们可以只关注活动算法的实现,每次我们新增一个活动,我们只需要实现PromotionCalculation 接口,并把对应实现类的资源路径存到数据库中就可以了,而不再需要改额外的代码。

总结

1.策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们可以相互替换,让算法独立于使用它们的用户而独立变化。

2.工厂模式主要负责实例的创建,工厂模式分为,简单工厂,工厂方法,抽象工厂3种。本文只介绍了简单工厂,感兴趣的朋友可以看看另外两种的写法。

3.设计模式远不止这些,比如装饰者模式,代理模式,责任链模式,桥接模式,适配器模式,外观模式,观察者模式等等。熟练的运用这些设计模式,能极大减少冗余代码。
最后,引用授业恩师一句话:不会偷懒的程序员不是好程序员。多思考,多总结,才能走得更远。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值