行为型设计模式之--模板方法模式

模板方法实际就是封装固定的流程,像模板一样,第一步做什么,第二步又做什么,都在抽象类中定义好。子类可以有不同的算法实现,在算法框架不被修改的前提下实现某些步骤的算法替换。

在我们的水果店中,清点商品、计算价目、用户支付、送货上门这四个步骤是固定下来的。但是其中用户支付的方式有多种多样,这个是不确定的,而且后续是否会添加新的支付方式也不得而知,因此,用户支付这个步骤可以做成一个接口,延迟到子类中再去实现,这样就有了更好的扩展性。

ShoppingCart是我们的模板方法模式的抽象类,里面定义好了一系列的固定步骤,只有pay()方法是接口没有实现。

/**
 * 模板方法模式
 * 购物车费用结算过程
 */
public abstract class ShoppingCart {
    private Discount discount;
    private List<Fruit> products = new ArrayList<>();

    public ShoppingCart(List<Fruit> products){
        this.products = products;
    }

    public void setDiscount(Discount discount) {
        this.discount = discount;
    }

    //提交订单主流程
    public void submitOrder(){
        //计算商品金额
        int money = balance();
        System.out.println("商品总金额为:"+money+"元");

        //优惠减免
        money = discount.calculate(money);
        System.out.println("优惠减免后:"+ money+"元,");

        //保存订单
        pay(money);

        //送货上门
        sendHome();

    }

    //计算金额
    private int balance(){
        int money = 0;
        System.out.print("商品清单:");
        for (Fruit fruit : products){
            fruit.draw();
            System.out.print(",");
            money += fruit.price();
        }
        return money;
    }

    private void sendHome(){
        System.out.println("三公里以内,免费送货上门");
    }

    //提交保存
    protected abstract void pay(int money);

}

下面是四种不同的支付方式:

/**
 * 模板方法模式
 * 购物车费用结算过程
 */
public class CartShopping extends ShoppingCart{

    public CartShopping(List<Fruit> products) {
        super(products);
    }

    @Override
    protected void pay(int money) {
        System.out.println("会员卡结算,立减10,金额:"+ (money - 10)+",增加积分:"+10*money);
    }
}


/**
 * 模板方法模式
 * 购物车费用结算过程
 */
public class CashShopping extends ShoppingCart{


    public CashShopping(List<Fruit> products) {
        super(products);
    }

    @Override
    protected void pay(int money) {
        System.out.println("现金结算,假一罚十");
    }
}


/**
 * 模板方法模式
 * 购物车费用结算过程
 */
public class OnlineShopping extends ShoppingCart{
    private OrderService orderService = new OrderServiceImpl();

    public OnlineShopping(List<Fruit> products) {
        super(products);
    }
    @Override
    protected void pay(int money) {
        System.out.println("微信/支付宝结算,减免5元,请支付:"+(money - 5)+"元");
        int orderId = orderService.saveOrder();

    }
}


/**
 * 模板方法模式
 * 其他人代付费用结算过程
 */
public class OtherPayShopping extends ShoppingCart{

    public OtherPayShopping(List<Fruit> products) {
        super(products);
    }

    @Override
    protected void pay(int money) {
        System.out.println("代付成功");
    }
}

最终在使用时:

/**
 * 模板方法模式
 * 订单费用结算过程
 */
public class ShoppingCartClient {

    private static Map<String, Discount> disCounts = new HashMap();
    static {
        disCounts.put("full",new FullDiscount());
        disCounts.put("newer",new NewerDiscount());
        disCounts.put("second",new SecondDiscount());
    }

    public static void main(String[] args) {
        List<Fruit> products = new ArrayList();

        products.add(StaticFactory.getFruitApple());
        products.add(StaticFactory.getFruitBanana());
        products.add(StaticFactory.getFruitOrange());

        ShoppingCart cart = new OnlineShopping(products);

        //注入优惠方案
//        String discount = "second";
//        cart.setDiscount(disCounts.get(discount));

        cart.submitOrder();
    }
}

在软件开发中遇到类似的情况:某个方法的实现需要多个步骤,其中有些步骤是固定的;而有些步骤并不固定,存在可变性。为了提高代码的复用性和系统的灵活性,可以使用模板方法模式来应对这类情况。
定义:定义一个操作中的算法框架,而将一些步骤延迟到子类中,使得子类不改变一个算法的结构即可重定义算法的某些特定步骤。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值