`
DavyJones2010
  • 浏览: 151872 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

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);
				}
			}
		}
	}
}
  • 大小: 24.2 KB
  • 大小: 43.4 KB
  • 大小: 49.9 KB
分享到:
评论

相关推荐

    DesignPattern::pencil:设计模式_java实现以及详解

    本资源“DesignPattern::pencil:设计模式_java实现以及详解”提供了一套详细的学习材料,帮助开发者理解和应用设计模式。 该资源的作者是“养码青年-Style”,他通过这个项目记录了自己的设计模式学习过程。鼓励...

    DesignPattern:C#设计模式示例

    "DesignPattern:C#设计模式示例"这个资源很可能是包含多个C#实现的设计模式示例代码库。 设计模式通常分为三类:创建型、结构型和行为型。每种模式都解决了特定场景下的问题,并提供了良好的代码组织和扩展性。 ...

    DesignPattern:设计模式小Demo

    设计模式是软件工程中的一种最佳实践,用于解决在软件设计中常见的...以上就是这个DesignPattern小Demo中可能会涵盖的设计模式,通过这些模式的实例,你可以更好地理解和应用它们到实际项目中,提升你的Java编程能力。

    DesignPattern:这是针对不同设计人员的测试项目

    这个名为"DesignPattern:这是针对不同设计人员的测试项目"的压缩包,显然是一个与设计模式相关的学习或测试资源,特别关注的是Java语言的应用。Scott可能是该项目的创建者或者主要贡献者,而“调整”可能指的是对...

    DesignPattern:来自 http 的设计模式参考

    在"DesignPattern-master"这个压缩包中,可能包含了这些模式的Java实现示例,以及相关的解释和用法说明。通过学习和应用这些模式,开发者可以提高代码质量,降低维护成本,并提升软件系统的可扩展性。对于任何Java...

    DesignPattern:有关设计模式的一些演示

    这个名为"DesignPattern:有关设计模式的一些演示"的项目,可能是为了帮助开发者理解和应用各种设计模式。 设计模式分为三大类:创建型、结构型和行为型。创建型模式关注对象的创建过程,如单例(Singleton)、工厂...

    DesignPattern:设计模式

    DesignPattern-master这个压缩包可能包含了一个关于设计模式的项目或者教程资源。 设计模式分为三类:创建型模式(Creational Patterns)、结构型模式(Structural Patterns)和行为型模式(Behavioral Patterns)...

    DesignPattern:设计模式.net源代码

    本资源"DesignPattern:设计模式.net源代码"提供了一套基于.NET实现的设计模式示例,旨在帮助程序员更好地理解和应用这些模式。 在"DesignPattern-master"这个压缩包中,你可能找到的文件结构和内容包括: 1. **...

    designpattern:Head First 设计模式练习

    策略模式(Strategy)定义了一系列算法,并将每个算法封装起来,使它们可以相互替换。Java中的Comparator接口就是一个策略的例子,你可以根据需要提供不同的比较策略。 代理模式(Proxy)为其他对象提供一种代理以...

    designPattern:设计模式相关代码实现

    "designPattern:设计模式相关代码实现"这个项目,显然提供了不同设计模式在Java语言中的实际应用示例。 在Java世界里,设计模式主要分为三大类:创建型模式、结构型模式和行为型模式。每种模式都针对特定的编程问题...

    DesignPattern:设计模式演示程序

    这个名为"DesignPattern"的压缩包文件很可能包含了一个Java实现的各种设计模式的示例程序。 在这个"DesignPattern-master"目录中,我们可以期待找到一系列与设计模式相关的Java源代码文件(.java),每个文件或...

    Design Pattern英文版

    设计模式(Design Pattern)是软件工程中的一种经验总结,它是在特定上下文中为解决常见问题而提出的一套可复用的解决方案。设计模式并不直接实现为代码,而是提供了一种在面向对象设计中如何处理常见问题的指南。...

    Design*Pattern*Framework*4.5

    "Design*Pattern*Framework*4.5" 可能指的是一个基于 .NET Framework 4.5 的设计模式实现或教程集合。 设计模式是经验丰富的软件开发者的智慧结晶,它们被分为三类:创建型、结构型和行为型。创建型模式涉及对象的...

    designPattern:코딩사전님의정정정리

    "designPattern:코딩사전님의정정정리"可能是某位名为"정정전"的专家或教师对设计模式进行整理和修正后的资料集合,旨在帮助开发者更好地理解和应用这些模式。 首先,设计模式分为三大类:创建型、结构型和行为型...

    Design Pattern 简明手册

    ### Design Pattern 简明手册知识点详述 #### 一、接口型(interface)模式 **1. Adapter(适配器模式)** - **定义**:允许一个类接口与另一个不兼容的类接口协同工作。 - **分类**: - **继承型Adapter**:通过...

    DesignPattern:关于设计模式

    在这个“DesignPattern”仓库中,可能包含了对各种设计模式的详细解释、示例和应用。 设计模式分为三大类:创建型、结构型和行为型模式。创建型模式主要关注对象的创建过程,如单例模式(Singleton)、工厂模式...

    阅读java源码-JavaDesignPattern:23种设计模式Java实现

    在“阅读java源码-JavaDesignPattern:23种设计模式Java实现”中,我们将深入探讨这23种设计模式的Java实现。 1. **创建型模式**(Creational Patterns): - **单例模式(Singleton)**:确保一个类只有一个实例,...

    Java-DesignPattern:Java中23种常见的设计模式

    本资料包“Java-DesignPattern:Java中23种常见的设计模式”涵盖了软件设计中的重要概念,以下是这些模式的详细说明: 1. **单例模式(Singleton)**:确保一个类只有一个实例,并提供全局访问点。防止其他对象多次...

    C++设计模式(Design Pattern)范例源代码

    23种设计模式(Design Pattern)的C++实现范例,包括下面列出的各种模式,代码包含较详细注释。另外附上“设计模式迷你手册.chm”供参考。 注:项目在 VS2008 下使用。 创建型: 抽象工厂模式(Abstract Factory) 生成...

Global site tag (gtag.js) - Google Analytics