栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

设计模式-创建型模式-策略模式-1

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

设计模式-创建型模式-策略模式-1

策略模式

策略模式定义了一系列算法,封装了这些算法,并使它们可以互换;

策略模式属于对象的行为模式。其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化

注:基于面向对象的特性:多态;

1.实现类图

  • context : 运行特定策略的类;
  • ConcreteStrategy1 ,ConcreteStrategy2,ConcreteStrategy3 具体的策略实现
  • Strategy: 抽象的策略;
2.简单实现
public interface Strategy {
	void algorithm();
}


public class Context {

	private Strategy strategy;

	public Context(Strategy strategy) {
		this.strategy = strategy;
	}

	
	public void invokeAlgorithm() {
		strategy.algorithm();
	}
}

public class ConcreteStrategy1 implements Strategy{
    @Override
    public void algorithm() {
        System.out.println("1111111111");
    }
}

public class ConcreteStrategy2 implements Strategy {
	@Override
	public void algorithm() {
		System.out.println("222222222");
	}
}

public class ConcreteStrategy1 implements Strategy{
    @Override
    public void algorithm() {
        System.out.println("1111111111");
    }
}

可以看到 是 实现是 基于面向对象的特性:多态;

3.JDK 的实现
Collections

public static  void sort(List list, Comparator c)

集合的工具类对List 安装指定的比较器(可以看做是Strategy 的实现)排序

4.模拟JDK 的实现

场景:对类 Rectangle Square 按照属性排序

4.1 第一版
public class Rectangle {

	int width;

	int height;

	public Rectangle(int width, int height) {
		this.width = width;
		this.height = height;
	}

	@Override
	public String toString() {
		return "Rectangle{" + "width=" + width + ", height=" + height + '}';
	}
}


public class Square {

	int length;

	public Square(int length) {
		this.length = length;
	}

	@Override
	public String toString() {
		return "Square{" + "length=" + length + '}';
	}
}

一般做法就是 写两个工具类分别对这两个类属性做判断 并且排序 如下

// 对 	 Rectangle 按照 width 排序
public static void sort(Rectangle[] arr) {
		for (int i = 0; i < arr.length; i++) {
			int min = i;
			for (int j = i + 1; j < arr.length; j++) {
				min = arr[j].width - arr[min].width < 0 ? j : min;
			}
			Rectangle temp = arr[i];
			arr[i] = arr[min];
			arr[min] = temp;
		}
	}
  
//对    Square 按照 length 排序
	public static void sort(Square[] arr) {
		for (int i = 0; i < arr.length; i++) {
			int min = i;
			for (int j = i + 1; j < arr.length; j++) {
				min = arr[j].length - arr[min].length < 0 ? j : min;
			}
			Square temp = arr[i];
			arr[i] = arr[min];
			arr[min] = temp;
		}
	}

可以看到是相对冗余代码比较多 ,只有一部分是不同的,当然可以简化下 如下

4.2 第二版

抽取一个属性对比方法 ,

public interface ShapeComparable {
	int compare(T o1);
}
public class Rectangle implements ShapeComparable{
    .....
    //添加方法
    @Override
	public int compare(Rectangle o1) {
		return this.width - o1.width;
	}
}
 
public class Square implements ShapeComparable {
     .....
    //添加方法
	@Override
	public int compare(Square o1) {
		return this.length - o1.length;
	}
}

修改后 sort 方法就可以简化为一个方法

public class SortUtil {

	public static void sort(ShapeComparator[] arr) {
		for (int i = 0; i < arr.length; i++) {
			int min = i;
			for (int j = i + 1; j < arr.length; j++) {
				min = arr[j].compare(arr[min]) < 0 ? j : min;
			}
			ShapeComparator temp = arr[i];
			arr[i] = arr[min];
			arr[min] = temp;
		}
	}
}

排序方法简化成一个,很简化了,排序的时候都调用compare , 来判断大小

问题: Rectangle 的另一个字段比较怎么办? 修改 compare 方法的代码? ,两个比较都想要怎么处理;

最好是不要修改原来 compare 的代码 (对修改关闭,对扩展开发 原则)

所以上面的设计并不是最好的设计!

4.3 第三版

Rectangle 和 Square 保持和第一版一样不变

新增 ShapeComparator 比较器接口 ,可以看做是策略(Strategy )的抽象类

public interface ShapeComparator {

	int compareTo(T o1, T o2);
}
//比较方法修改,排序的时候,执行自定义的排序策略
public class SortUtil {

	public static  void sort(T[] arr, ShapeComparator shapeComparator) {
		for (int i = 0; i < arr.length; i++) {
			int min = i;
			for (int j = i + 1; j < arr.length; j++) {
				min = shapeComparator.compareTo(arr[j], arr[min]) < 0 ? j : min;
			}
			T temp = arr[i];
			arr[i] = arr[min];
			arr[min] = temp;
		}
	}
}

我们自定义的比较器,可以是任意扩展的,这样对 类的排序就很灵活,扩展性也有很大的提高;

示例: 两个比较器都是 对 Rectangle 的排序,这个可以无线扩展,规则可以任意制定;

public class RectangleComparator1 implements ShapeComparator {

    @Override
    public int compareTo(Rectangle o1, Rectangle o2) {
        return o1.width - o2.width;
    }
}

public class RectangleComparator2 implements ShapeComparator {

	@Override
	public int compareTo(Rectangle o1, Rectangle o2) {
		return o1.height - o2.height;
	}
}
public static void main(String[] args) {
		Rectangle rectangle = new Rectangle(2344, 1);
		Rectangle rectangle1 = new Rectangle(23423, 9);
		Rectangle rectangle2 = new Rectangle(65756, 8);
		Rectangle rectangle3 = new Rectangle(544, 7);

		Rectangle arr[] = { rectangle, rectangle1, rectangle2, rectangle3 };
		SortUtil.sort(arr, new RectangleComparator1());
		for (Rectangle rectangle4 : arr) {
			System.out.println(rectangle4);
		}
		SortUtil.sort(arr, new RectangleComparator2());
		for (Rectangle rectangle5 : arr) {
			System.out.println(rectangle5);
		}
}
4.4 总结

模拟JDK Collections.sort() ,JDK 中这个方法可以根据使用者自定义的策略对List 内容排序;排序规则可以任意指定,可扩展性非常高;只需要自己指定是如何比较;

注 :我们编写的 ShapeComparator和 JDK 的 Comparator接口 类似;

第三版的ShapeComparator 接口JDK 也有,Collections.sort() 不指定Comparator 就会走对象的实现的Comparable接口;

public static > void sort(List list) 
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/889115.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号