DesignPattern : Strategy

1. Introduction

    Look at the example below:

    We want to sort an array of integer.

    1) Test case

package edu.xmu.designPattern.DesignPattern_Strategy;

import java.util.ArrayList;
import java.util.List;

import org.junit.Before;
import org.junit.Test;

public class StrategyTest
{
	private List<Integer> dataList = new ArrayList<Integer>();

	@Before
	public void setUp()
	{
		dataList.add(1);
		dataList.add(0);
		dataList.add(2);
		dataList.add(-11);
		dataList.add(100);
	}

	@Test
	public void test()
	{
		DataSorter.ascSort(dataList);

		for (Integer data : dataList)
		{
			System.out.println(data + ", ");
		}
		System.out.println("====================================");
		
		DataSorter.descSort(dataList);

		for (Integer data : dataList)
		{
			System.out.println(data + ", ");
		}
	}
}

   2) Core function

package edu.xmu.designPattern.DesignPattern_Strategy;

import java.util.List;

public class DataSorter
{
	public static void ascSort(List<Integer> dataList)
	{
		// bubble sort
		for (int i = 0; i < dataList.size(); i++)
		{
			for (int j = 0; j < dataList.size() - i - 1; j++)
			{
				if (dataList.get(j) > dataList.get(j + 1))
				{
					swap(dataList, j, j + 1);
				}

			}
		}
	}
	private static void swap(List<Integer> dataList, int i, int j)
	{
		int temp = dataList.get(i);
		dataList.set(i, dataList.get(j));
		dataList.set(j, temp);
	}

	public static void descSort(List<Integer> dataList)
	{
		// bubble  sort
		for (int i = 0; i < dataList.size(); i++)
		{
			for (int j = 0; j < dataList.size() - i - 1; j++)
			{
				if (dataList.get(j) < dataList.get(j + 1))
				{
					swap(dataList, j, j + 1);
				}

			}
		}
	}
}

   The solution above is quite simple and easy to understand.

   But what if we want to sort an array contains a more complex data type, how should we implements?

 

2. Example as below:

    1) Bean we want to sort

package edu.xmu.designPattern.DesignPattern_Strategy;

public class Cat
{
	private int height;
	private int weight;

	public int getHeight()
	{
		return height;
	}

	public void setHeight(int height)
	{
		this.height = height;
	}

	public int getWeight()
	{
		return weight;
	}

	public void setWeight(int weight)
	{
		this.weight = weight;
	}

}

   2) The core function (Here we are using the height of cat as comparision element)

package edu.xmu.designPattern.DesignPattern_Strategy;

import java.util.List;

public class DataSorter
{
	public static void ascSort(List<Cat> dataList)
	{
		// bubble sort
		for (int i = 0; i < dataList.size(); i++)
		{
			for (int j = 0; j < dataList.size() - i - 1; j++)
			{
				if (dataList.get(j).getHeight() > dataList.get(j + 1)
						.getHeight())
				{
					swap(dataList, j, j + 1);
				}

			}
		}
	}

	private static void swap(List<Cat> dataList, int i, int j)
	{
		Cat temp = dataList.get(i);
		dataList.set(i, dataList.get(j));
		dataList.set(j, temp);
	}

	public static void descSort(List<Cat> dataList)
	{
		// bubble sort
		for (int i = 0; i < dataList.size(); i++)
		{
			for (int j = 0; j < dataList.size() - i - 1; j++)
			{
				if (dataList.get(j).getHeight() < dataList.get(j + 1)
						.getHeight())
				{
					swap(dataList, j, j + 1);
				}

			}
		}
	}
}

   3) Test case

package edu.xmu.designPattern.DesignPattern_Strategy;

import java.util.ArrayList;
import java.util.List;

import org.junit.Before;
import org.junit.Test;

public class StrategyTest
{
	private List<Cat> dataList = new ArrayList<Cat>();

	@Before
	public void setUp()
	{
		dataList.add(new Cat(1, 1));
		dataList.add(new Cat(0, 2));
		dataList.add(new Cat(-1, 2));
		dataList.add(new Cat(-11, 2));
		dataList.add(new Cat(100, -1));
	}

	@Test
	public void test()
	{
		DataSorter.ascSort(dataList);

		for (Cat data : dataList)
		{
			System.out.println(data + ", ");
		}
		System.out.println("====================================");

		DataSorter.descSort(dataList);

		for (Cat data : dataList)
		{
			System.out.println(data + ", ");
		}
	}
}

   Comments:

        1) It seems that our DataSorter can be used for a random kind of Object.

        2) But what if we want use this to sort an array contains Dog?

            We have to change the code inside the sort function.

        3) What if when the height of cats are the same, we want to sort by weight?

            We have to change the code inside the sort function.

         Simply speaking, our sorter is tightly coupled with the class it want to sort.

 

3. A better approach for explaining Comparable interface

    1) Comparable interface

package edu.xmu.designPattern.DesignPattern_Strategy;

public interface Comparable
{
	public int compare(Comparable o);
}

    2) Cat class that implements this interface

package edu.xmu.designPattern.DesignPattern_Strategy;

public class Cat implements Comparable
{
	private int height;
	private int weight;

	public Cat(int height, int weight)
	{
		super();
		this.height = height;
		this.weight = weight;
	}

	public int getHeight()
	{
		return height;
	}

	public void setHeight(int height)
	{
		this.height = height;
	}

	public int getWeight()
	{
		return weight;
	}

	public void setWeight(int weight)
	{
		this.weight = weight;
	}

	@Override
	public String toString()
	{
		return "Cat [height=" + height + ", weight=" + weight + "]";
	}

	public int compare(Comparable o)
	{
		Cat c = (Cat) o;
		return this.getHeight() >= c.getHeight() ? (this.getHeight() == c
				.getHeight() ? (this.getWeight() >= c.getWeight() ? 1 : -1) : 1)
				: -1;
	}

}

   3) DataSort class that coupled with interface Comparable instead of concrete class

package edu.xmu.designPattern.DesignPattern_Strategy;

import java.util.List;

public class DataSorter
{
	public static void ascSort(List<Comparable> dataList)
	{
		// bubble sort
		for (int i = 0; i < dataList.size(); i++)
		{
			for (int j = 0; j < dataList.size() - i - 1; j++)
			{
				if (1 == dataList.get(j).compare(dataList.get(j + 1)))
				{
					swap(dataList, j, j + 1);
				}

			}
		}
	}

	private static void swap(List<Comparable> dataList, int i, int j)
	{
		Comparable temp = dataList.get(i);
		dataList.set(i, dataList.get(j));
		dataList.set(j, temp);
	}

	public static void descSort(List<Comparable> dataList)
	{
		// bubble sort
		for (int i = 0; i < dataList.size(); i++)
		{
			for (int j = 0; j < dataList.size() - i - 1; j++)
			{
				if (-1 == dataList.get(j).compare(dataList.get(j + 1)))
				{
					swap(dataList, j, j + 1);
				}
			}
		}
	}
}

  4) Test case

package edu.xmu.designPattern.DesignPattern_Strategy;

import java.util.ArrayList;
import java.util.List;

import org.junit.Before;
import org.junit.Test;

public class StrategyTest
{
	private List<Comparable> dataList = new ArrayList<Comparable>();

	@Before
	public void setUp()
	{
		dataList.add(new Cat(1, 1));
		dataList.add(new Cat(0, 2));
		dataList.add(new Cat(-1, 2));
		dataList.add(new Cat(-11, 2));
		dataList.add(new Cat(100, -1));
	}

	@Test
	public void test()
	{
		DataSorter.ascSort(dataList);
		for (Comparable data : dataList)
		{
			System.out.println(data + ", ");
		}
	}
}

   Class Diagram:

    Comments:

        1) By using this, we simply decoupling the compare function with the sort function.

        2) Think of the System.out.println(obj) is simply call the obj.toString() instead of using other approach.

            This decoupled the two kinds of class.

         3) This is quite the same with the interface in JDK called java.lang.Comparable

 

4. A even more better approach

    1) When we came up with the way we used above. It seems all right.

        But what if we want to change the compare strategy for a cat?

        We have to change the code inside the Cat class.

        What if we want a certain list of cat compare based on the height + weight, and another list of cat compare based on the weight + height?

        The way before cannot realize this.

    2) The solution above couples the class with the compare function.

         And the compare function is not extensiable.

    3) The class diagram is as below


    1. Cat.java

package edu.xmu.designPattern.DesignPattern_Strategy;

public class Cat
{
	private int height;
	private int weight;

	public Cat(int height, int weight)
	{
		super();
		this.height = height;
		this.weight = weight;
	}

	public int getHeight()
	{
		return height;
	}

	public void setHeight(int height)
	{
		this.height = height;
	}

	public int getWeight()
	{
		return weight;
	}

	public void setWeight(int weight)
	{
		this.weight = weight;
	}

	@Override
	public String toString()
	{
		return "Cat [height=" + height + ", weight=" + weight + "]";
	}
}

    2.Comparator interface

package edu.xmu.designPattern.DesignPattern_Strategy;

public interface Comparator
{
	public int compare(Object obj1, Object obj2);
}

    3. One kind of compare strategy for Cat

package edu.xmu.designPattern.DesignPattern_Strategy;

public class CatComparatorBasedOnWeight implements Comparator
{

	public int compare(Object obj1, Object obj2)
	{
		Cat cat1 = (Cat) obj1;
		Cat cat2 = (Cat) obj2;

		return cat1.getWeight() >= cat2.getWeight() ? (cat1.getWeight() == cat2
				.getWeight() ? (cat1.getHeight() >= cat2.getHeight() ? 1 : -1)
				: 1) : -1;
	}

}

    4. Another kind of compare strategy for Cat

package edu.xmu.designPattern.DesignPattern_Strategy;

public class CatComparatorBasedOnHeight implements Comparator
{

	public int compare(Object obj1, Object obj2)
	{
		Cat cat1 = (Cat) obj1;
		Cat cat2 = (Cat) obj2;

		return cat1.getHeight() >= cat2.getHeight() ? (cat1.getHeight() == cat2
				.getHeight() ? (cat1.getWeight() >= cat2.getWeight() ? 1 : -1)
				: 1) : -1;
	}

}

    5. The core sort function

package edu.xmu.designPattern.DesignPattern_Strategy;

import java.util.List;

public class DataSorter
{
	public static void ascSort(List<Object> dataList, Comparator comparator)
	{
		// bubble sort
		for (int i = 0; i < dataList.size(); i++)
		{
			for (int j = 0; j < dataList.size() - i - 1; j++)
			{
				if (1 == comparator.compare(dataList.get(j),
						dataList.get(j + 1)))
				{
					swap(dataList, j, j + 1);
				}

			}
		}
	}

	private static void swap(List<Object> dataList, int i, int j)
	{
		Object temp = dataList.get(i);
		dataList.set(i, dataList.get(j));
		dataList.set(j, temp);
	}

	public static void descSort(List<Object> dataList, Comparator comparator)
	{
		// bubble sort
		for (int i = 0; i < dataList.size(); i++)
		{
			for (int j = 0; j < dataList.size() - i - 1; j++)
			{
				if (-1 == comparator.compare(dataList.get(j),
						dataList.get(j + 1)))
				{
					swap(dataList, j, j + 1);
				}
			}
		}
	}
}

    6. The test case

package edu.xmu.designPattern.DesignPattern_Strategy;

import java.util.ArrayList;
import java.util.List;

import org.junit.Before;
import org.junit.Test;

public class StrategyTest
{
	private List<Object> dataList = new ArrayList<Object>();

	@Before
	public void setUp()
	{
		dataList.add(new Cat(1, 1));
		dataList.add(new Cat(0, 2));
		dataList.add(new Cat(-1, 2));
		dataList.add(new Cat(-11, 2));
		dataList.add(new Cat(100, -1));
	}

	@Test
	public void test()
	{
		DataSorter.ascSort(dataList, new CatComparatorBasedOnWeight());
		for (Object data : dataList)
		{
			System.out.println(data + ", ");
		}
	}
}

    Comments:

         1) By using this, we simply decoupling the compare function with the real object.

         2) And we decoupled the sort function with the real object.which can easily be seen in the class diagram above.

         3) We can even add an attribute in class Cat called comparator and then Cat implements Comparable which has a compareTo method and its realization is use this comparator to get result.

 

5. A far more better approach

    1. Class diagram is as below


     2. Cat.java

package edu.xmu.designPattern.DesignPattern_Strategy;

public class Cat implements Comparable
{
	private int height;
	private int weight;

	private Comparator comparator = new CatComparatorBasedOnHeight();

	public Cat(int height, int weight)
	{
		super();
		this.height = height;
		this.weight = weight;
	}

	public int getHeight()
	{
		return height;
	}

	public void setHeight(int height)
	{
		this.height = height;
	}

	public int getWeight()
	{
		return weight;
	}

	public void setWeight(int weight)
	{
		this.weight = weight;
	}

	public Comparator getComparator()
	{
		return comparator;
	}

	public void setComparator(Comparator comparator)
	{
		this.comparator = comparator;
	}

	@Override
	public String toString()
	{
		return "Cat [height=" + height + ", weight=" + weight + "]";
	}

	public int compare(Comparable o)
	{
		return comparator.compare(this, o);
	}
}

    3. Core sort function

package edu.xmu.designPattern.DesignPattern_Strategy;

import java.util.List;

public class DataSorter
{
	public static void ascSort(List<Comparable> dataList)
	{
		// bubble sort
		for (int i = 0; i < dataList.size(); i++)
		{
			for (int j = 0; j < dataList.size() - i - 1; j++)
			{
				if (1 == dataList.get(j).compare(dataList.get(j + 1)))
				{
					swap(dataList, j, j + 1);
				}

			}
		}
	}

	private static void swap(List<Comparable> dataList, int i, int j)
	{
		Comparable temp = dataList.get(i);
		dataList.set(i, dataList.get(j));
		dataList.set(j, temp);
	}

	public static void descSort(List<Comparable> dataList)
	{
		// bubble sort
		for (int i = 0; i < dataList.size(); i++)
		{
			for (int j = 0; j < dataList.size() - i - 1; j++)
			{
				if (-1 == dataList.get(j).compare(dataList.get(j + 1)))
				{
					swap(dataList, j, j + 1);
				}
			}
		}
	}
}
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值