@Tyhj 2019-01-31T07:20:57.000000Z 字数 4092 阅读 750

# 策略模式

设计模式

### 使用场景

• 针对同一种问题的多种处理方式，仅仅是具体行为有差别时
• 需要安全地封装同一种类型的操作的时候
• 出现同一抽象类有多个子类，而又需要使用if-else 或者 swith-case来选择具体子类时

### 举个栗子

public interface LikeColor {    /**     * 两种颜色是否相似     *     * @param color1     * @param color2     * @param aberration 允许差异值     * @return     */    boolean isLike(int color1, int color2, double aberration);}

public class HsvColorLike implements LikeColor {    @Override    public boolean isLike(int color1, int color2, double aberration) {        if (hsvAberration(color1, color2) <= aberration) {            return true;        }        return false;    }    /**     * HSV颜色空间计算颜色距离     */    public static double hsvAberration(int color1, int color2) {        float[] tempHSV1 = new float[3];        Color.colorToHSV(color1, tempHSV1);        float[] tempHSV2 = new float[3];        Color.colorToHSV(color2, tempHSV2);        HSV hsv1 = new HSV();        hsv1.H = tempHSV1[0];        hsv1.S = tempHSV1[1];        hsv1.V = tempHSV1[2];        HSV hsv2 = new HSV();        hsv2.H = tempHSV2[0];        hsv2.S = tempHSV2[1];        hsv2.V = tempHSV2[2];        return HSV.distanceOf(hsv1, hsv2);    }    public static class HSV {        public float H;        public float S;        public float V;        //self-defined        private static final double R = 100;        private static final double angle = 30;        private static final double h = R * Math.cos(angle / 180 * Math.PI);        private static final double r = R * Math.sin(angle / 180 * Math.PI);        /**         * HSV颜色空间计算颜色距离         * HSV是个六棱锥模型,这个模型中颜色的参数分别是：色调（H），饱和度（S），明度（V）         *         * @param hsv1         * @param hsv2         * @return         */        public static double distanceOf(HSV hsv1, HSV hsv2) {            double x1 = r * hsv1.V * hsv1.S * Math.cos(hsv1.H / 180 * Math.PI);            double y1 = r * hsv1.V * hsv1.S * Math.sin(hsv1.H / 180 * Math.PI);            double z1 = h * (1 - hsv1.V);            double x2 = r * hsv2.V * hsv2.S * Math.cos(hsv2.H / 180 * Math.PI);            double y2 = r * hsv2.V * hsv2.S * Math.sin(hsv2.H / 180 * Math.PI);            double z2 = h * (1 - hsv2.V);            double dx = x1 - x2;            double dy = y1 - y2;            double dz = z1 - z2;            return Math.sqrt(dx * dx + dy * dy + dz * dz);        }    }}

public class LabColorLike implements LikeColor {    @Override    public boolean isLike(int color1, int color2, double aberration) {        if (labAberration(color1, color2) <= aberration) {            return true;        }        return false;    }    /**     * LAB颜色空间计算色差，基于人眼对颜色的感知，     * 可以表示人眼所能感受到的所有颜色。     * L表示明度，A表示红绿色差，B表示蓝黄色差     */    public static int labAberration(int color1, int color2) {        int r1 = Color.red(color1); // 取高两位        int g1 = Color.green(color1);// 取中两位        int b1 = Color.blue(color1);// 取低两位        int r2 = Color.red(color2); // 取高两位        int g2 = Color.green(color2);// 取中两位        int b2 = Color.blue(color2);// 取低两位        int rmean = (r1 + r2) / 2;        int r = r1 - r2;        int g = g1 - g2;        int b = b1 - b2;        return (int) Math.sqrt((2 + rmean / 256) * (Math.pow(r, 2)) + 4 * (Math.pow(g, 2)) + (2 + (255 - rmean) / 256) * (Math.pow(b, 2)));    }}

public class RgbColorLike implements LikeColor {    @Override    public boolean isLike(int color1, int color2, double aberration) {        return baseLike(color1, color2, aberration);    }    /**     * @param color1 第一种颜色     * @param color2 第二种颜色     * @return     */    public  boolean baseLike(int color1, int color2, double aberration) {        int red = Color.red(color1); // 取高两位        int green = Color.green(color1);// 取中两位        int blue = Color.blue(color1);// 取低两位        int red2 = Color.red(color2); // 取高两位        int green2 = Color.green(color2);// 取中两位        int blue2 = Color.blue(color2);// 取低两位        if (red == red2 && green == green2 && blue == blue2) {            return true;        }        if ((Math.abs(red - red2) < aberration && Math.abs(green - green2) < aberration && Math.abs(blue - blue2) < aberration) &&                (Math.abs(red - red2) + Math.abs(green - green2) + Math.abs(blue - blue2)) < aberration * 2.5) {            return true;        }        return false;    }    /**     * 简单的RGB颜色判断     *     * @return     */    public static void rgbAberration(int color1, int color2) {        int red1 = Color.red(color1); // 取高两位        int green1 = Color.green(color1);// 取中两位        int blue1 = Color.blue(color1);// 取低两位        int red2 = Color.red(color2); // 取高两位        int green2 = Color.green(color2);// 取中两位        int blue2 = Color.blue(color2);// 取低两位        int red = Math.abs(red1 - red2);        int green = Math.abs(green1 - green2);        int blue = Math.abs(blue1 - blue2);        LogUtils.e("RGB颜色判断：色差：" + red + "，" + green + "，" + blue + "，all：" + (red + green + blue));    }}

 /**     * 对比颜色     *     * @param color1     * @param color2     * @param aberration     * @return     */    public static boolean colorLike(int color1, int color2, int aberration, LikeColor labLike) {        return labLike.isLike(color1, color2, aberration);    }

• 私有
• 公开
• 删除