《读_Head_First_有感》_“装饰者模式”

2018-07-24  本文已影响20人  tjhuey

前言:
前沿技术一直在迭代,有一种东西是不会更新的,那就是设计模式的思想。 可以来学习学习设计模式的思维,巧妙设计!

[TOC]

1.官方话语

概述

设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结。

六大原则:

单一职责原则 (Single ResponsiBility Principle) 概括:应该有且仅有一个原因引起类的变更
里氏替换原则(liskov Substitution Principle ) 概括:基类出现的地方,子类一定可以出现
依赖倒转原则(Depndece Inversion Principle) 概括:针对接口编程,依赖于抽象而不是具体
接口隔离原则(Interface Segregation Principle) 概括:使用多个隔离的接口,比使用单个接口好 (细分接口,降低耦合)
迪米特法则 (Demeter Principle) 概括:实体应当尽量少的与其他类发生互相作用,使得系统功能模块相对独立
开闭原则(Open Close Principle) 概括: 对扩展开放,对修改关闭
合成复用原则 (Composite Reuse Principle) 概括:尽量使用合成/聚合的方式,少用继承

个人话语

概述

设计模式在代码层级中,是让你在某种业务场景刚开始设计时,能让未来的相关需求扩展极为方便的一个思想。
简单的说,在一开始设计好,扩展是很方便的,设计模式就是这个功劳者
对于我们本来就懒的开发人员来说,这是求之不得的。

六大原则

而对于六大原则,简单过一下就行,不用刻意理解,如果你会了面向对象和设计模式的使用,自然就遵循了。

今日主题

装饰模式: 概述:动态的给一个对象添加一些额外的职责,就增加功能来说,装饰器模式相比生成子类更为灵活

场景:

现在有一系列产品,需要计算他们的费用,而不同产品的可能有不同的费用,比如A产品有自己的利率费还有咨询费和服务费,B产品有自己的利率费还有服务费。

概述:

将扩展行为抽成装饰者,如将利率,咨询费和服务费抽成行为;将各种产品抽象成被装饰者,如产品A 产品B;装饰者和被装饰者通过继承产品关系,通过组合处理行为。

代码如下

'抽象元组件'代码

package top.huey.designpattern.decoration;

import java.math.BigDecimal;

/**
 * @author huey
 * @Description : 产品抽象类组件
 * @Date Created in 2018/7/22 10:40
 */
public abstract class Component {

    /**
     * @author huey
     * @Description : public 权限 子类修改
     * @Date Created in 2018/7/22 11:23
     */
    public String desc = "default Component";

    /**
     * @author huey
     * @Description : 默认描述
     * @Date Created in 2018/7/22 10:46
     */
    public void desc() {
        System.out.println(desc);
    }

    /**
     * @author huey
     * @Description : 产品计算自身利率金额
     * @Date Created in 2018/7/22 10:47
     */
    public abstract BigDecimal cost();
}


'产品被装饰者'代码

package top.huey.designpattern.decoration;

import java.math.BigDecimal;

/**
 * @author huey
 * @Description : A产品
 * @Date Created in 2018/7/22 11:02
 */
public class AProduct extends Component{

    /**
     * @author huey
     * @Description : 产品计算自身利率金额
     * @Date Created in 2018/7/22 10:47
     */
    @Override
    public BigDecimal cost() {
        //此处写死,真正业务,可根据数据库 产品利率映射表来得
        return new BigDecimal(4.50);
    }
}


/**
 * @author huey
 * @Description : B产品
 * @Date Created in 2018/7/22 11:02
 */
public class BProduct extends Component{


    /**
     * @author huey
     * @Description : 产品计算自身利率金额
     * @Date Created in 2018/7/22 10:47
     */
    @Override
    public BigDecimal cost() {
        //此处写死,真正业务,可根据数据库 产品利率映射表来得
        return new BigDecimal(5.50);
    }
}



'抽象装饰者组件'代码

package top.huey.designpattern.decoration;

/**
 * @author huey
 * @Description : 装饰着抽象类
 * 装饰着模式核心在于,装饰着和被装饰者有着共同的接口或者父类,继承来达到关联关系
 * 而行为扩展和装饰不是通过继承,而是通过组合。
 * 装饰着组合一个产品,做行为处理。
 * @Date Created in 2018/7/22 11:07
 */
public abstract class Decorator extends Component {

    /**
     * @author huey
     * @Description : 定义装饰的描述
     * @Date Created in 2018/7/22 11:16
     */
    public abstract void desc();
}


'产品装饰者'代码

package top.huey.designpattern.decoration;

import java.math.BigDecimal;

/**
 * @author huey
 * @Description : A产品咨询费 装饰
 * @Date Created in 2018/7/22 11:20
 */
public class AProductConsult extends Decorator {

    private Component AProduct;

    public AProductConsult(Component AProduct) {
        this.AProduct = AProduct;
    }

    /**
     * @author huey
     * @Description : 定义装饰的描述
     * @Date Created in 2018/7/22 11:16
     */
    @Override
    public void desc() {
        System.out.println(this.desc + this.getClass().getName().toString());
    }

    /**
     * @author huey
     * @Description : A产品计算咨询费和自己利率金额和
     * @Date Created in 2018/7/22 10:47
     */
    @Override
    public BigDecimal cost() {
        return this.AProduct.cost().add(new BigDecimal(0.25));
    }
}


package top.huey.designpattern.decoration;

import java.math.BigDecimal;

/**
 * @author huey
 * @Description : A产品的服务费装饰
 * @Date Created in 2018/7/22 11:20
 */
public class AProductService extends Decorator {

    private Component AProduct;

    public AProductService(Component AProduct) {
        this.AProduct = AProduct;
    }

    /**
     * @author huey
     * @Description : 定义装饰的描述
     * @Date Created in 2018/7/22 11:16
     */
    @Override
    public void desc() {
        System.out.println(this.desc + this.getClass().getName().toString());
    }

    /**
     * @author huey
     * @Description : A产品计算服务费和自己利率金额和
     * @Date Created in 2018/7/22 10:47
     */
    @Override
    public BigDecimal cost() {
        return this.AProduct.cost().add(new BigDecimal(0.75));
    }
}

package top.huey.designpattern.decoration;

import java.math.BigDecimal;

/**
 * @author huey
 * @Description : B产品的服务费装饰
 * @Date Created in 2018/7/22 11:20
 */
public class BProductService extends Decorator {

    private Component BProduct;

    public BProductService(Component BProduct) {
        this.BProduct = BProduct;
    }

    /**
     * @author huey
     * @Description : 定义装饰的描述
     * @Date Created in 2018/7/22 11:16
     */
    @Override
    public void desc() {
        System.out.println(this.desc + this.getClass().getName().toString());
    }

    /**
     * @author huey
     * @Description : B产品计算服务费和自己利率金额和
     * @Date Created in 2018/7/22 10:47
     */
    @Override
    public BigDecimal cost() {
        return this.BProduct.cost().add(new BigDecimal(0.75));
    }
}

'测试'代码

package top.huey.designpattern.decoration;

import org.junit.Test;

/**
 * @author huey
 * @Description : 装饰模式测试
 * @Date Created in 2018/7/22 11:31
 */
public class DecoratorTest {

    @Test
    public void test1() {
        Component aProduct = new AProduct();
        System.out.println("aProduct: " + aProduct.cost());
        Component bProduct = new BProduct();
        System.out.println("bProduct: " + bProduct.cost());
        AProductConsult aProductConsult = new AProductConsult(aProduct);
        AProductService aProductService = new AProductService(aProduct);
        System.out.println("aProductConsult" + aProductConsult.cost());
        System.out.println("aProductService" + aProductService.cost());
        BProductService bProductService = new BProductService(bProduct);
        System.out.println("bProductService" + bProductService.cost());
    }

}

读者须知:

1.本系列文章内容会比较简陋,望有兴趣读者还是fork源码,调试一下。(如果你看过该书,一定可以加深印象)
2.联想下实际运用的哪些业务场景用到该模式,哪些中间件用到该模式,是否自己能在业务中使用。
3.即使你现在用不到某些设计模式,但是还是应该理解其原理的。
4.当时理解并不意味着自己已会,可以自己尝试练习,并幻想一种业务场景,画画类图,设计一下。


coding 时,做到了如何落实;
writing时,做到了如何表达;
sharing时,做到了如何传授;
thinking时,做到了如何提升;

代码请参考码云:https://gitee.com/tjhuey/CodingGroup
设计模式相关概念请参考:http://naotu.baidu.com/file/5811bf42020e6a2d877b992cfca90d26

进度

上一篇下一篇

猜你喜欢

热点阅读