首页 > 代码库 > 从“假如有以下几种价格10,20,50,请你代码实现将他们排序输出”看着设计模式中的策略模式

从“假如有以下几种价格10,20,50,请你代码实现将他们排序输出”看着设计模式中的策略模式

         今天重温了一下策略模式,将自己的一些感悟与大家分享。。。本人只是技术渣渣,所理解的东西的难免会有很大的局限性甚至是错误,还请各位带着批判的眼光去看待。。。。不喜请勿吐槽


         定义:策略模式属于设计模式中的对象行为型模式,它将用到的算法单独抽象成一个单独的类。通常,我们在多个类完成同一件事情,仅仅完成的方式不同时,我们可以考虑使用这种设计模式。

         

         举例:相信,很多人在看到“假如有以下几种价格10,20,50,请你代码实现将他们排序输出”这种题目的时候,很快就写出了以下代码,写之前还不忘了问一下,“对时间复杂度有什么要求吗???需要处理的数据规模大概是多少???”,这时候,别人通常都会面带微笑,说,“对时间复杂度没有要求,数据规模你假设是XX就行了”之类的话。。。

        很快的,类似于下面的代码就出来了

         

/*
 * price.cpp
 *
 *  Created on: 2014年5月11日
 *      Author: pc
 */

#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;

int n;
int price[100];

/**
 * 处理输入逻辑
 */
void hanldeInput() {
	int i;
	for (i = 0; i < n; ++i) {
		scanf("%d", &price[i]);
	}
}

/**
 *相比这里很多朋友会绞尽脑汁的想各种各样的排序算法..
 *其实最后写出来的话,大部分用到的算法还是: 冒泡排序、选择排序、插入排序、希尔排序、快速排序、归并排序、堆排序
 */
void sort(int price[]) {
	for(int i = n ; i > 0 ; --i){
		for(int j = 0 ; j < i-1 ; ++j){
			if(price[j] > price[j+1]){
				swap(price[j],price[j+1]);
			}
		}
	}
}

/**
 * 处理输出逻辑
 */
void myprint(int price[]) {
	//TODO 此处将他们输出
	for(int i = 0 ; i < n ; ++i){
		printf("%d ",price[i]);
	}

}

int main() {
	while (scanf("%d", &n) != EOF) {
		hanldeInput();
		sort(price);
		myprint(price);
	}
}

       尽管有的朋友甚至可能还会把上面的输入逻辑、排序逻辑、输出逻辑都写到main方法里面,但是,大部分都会在写完以后在心里骂一句,“靠,老子是XX区的ACM的XX牌的获得者,居然拿这种题来敷衍我。。”靠。。。这是,只见别人还是一如既往的面带微笑。。。。然后就自我感觉非常良好地离开了。。。。


其实,现在再回首这种题目的时候,再看看若干年前自己写成那样的代码,简直不忍直视。。。

以下谈谈自己遇到类似的问题时,自己的一些思考。

个人觉得,这种题目可能更多关注的不是你的代码实现,而是你在写代码时的架构。


以下是自己的一些思考

1)根据OOP“一切皆对象”的原则,price应该设计成一个类,而不是仅仅是一个int[]。

2)上面的排序逻辑只能作用于Int[],要是某一天用户有一堆double[]类型的数据需要按同样的逻辑进行排序呢???

那你难道ctrl+c\ctrl+v一遍,然后把参数改成double[]类型的??现在的sort方法职能作用领域Price类型的数据,

要是某一天需要对Human类型的数据进行排序呢????难道又重写一遍逻辑类似的sort方法而仅仅是因为参数的

类型不一样???

3)上面的排序逻辑已经写死了,就是用的冒泡排序。要是某一天用户高兴,说我就是喜欢用希尔排序。那你是不是又要把那一坨代码改改改。。。这。。。


        这时,可能有一些朋友会说,“我才不管,反正他问的是:假如有以下几种价格10,20,50,请你代码实现将他们排序输出,我只要实现这一个逻辑就行了,管他呢”。。是的,其实这种题只是用户的某一种情况的下的需求的简化一下的版本而已。。。例如今天用户就只说,“我有一堆的Price,你帮我排序一下”,明天他可能就会对你说,“我也有一堆的Human,你也帮我排序一下吧”。。。后天有会对你说,“你之前的那个算法我不喜欢,你换一个吧”。。。。这是你会疯掉的。。。。


所以,以下给出我对这一情况下使用策略模式来设计代码的实现


1、MyComparable

public interface MyComparable {

	public int compareTo(Object o);
}


2、MyComparator

public interface MyComparator {

	public int compare(Object o1,Object o2);
}

3、PriceNumComparator

public class PriceNumComparator implements MyComparator {

	@Override
	public int compare(Object o1, Object o2) {
		Price p1 = (Price)o1;
		Price p2 = (Price)o2;
		
		if(p1.getNum() > p2.getNum()){
			return 1;
		}else if(p1.getNum() < p2.getNum()){
			return -1;
		}
		return 0;
	}
	
}

4、PriceWeightComparator

public class PriceWeightComparator implements MyComparator {

	@Override
	public int compare(Object o1, Object o2) {
		Price p1 = (Price)o1;
		Price p2 = (Price)o2;
		
		if(p1.getWeight() > p2.getWeight()){
			return -1;
		}else if(p1.getWeight() < p2.getWeight()){
			return 1;
		}
		
		return 0;
	}

}

5、Price

public class Price implements MyComparable{

	public int num;
	public int weight;
	public MyComparator comparator  = new PriceWeightComparator();
	
	public int getNum() {
		return num;
	}
	public void setNum(int num) {
		this.num = num;
	}
	public int getWeight() {
		return weight;
	}
	public void setWeight(int weight) {
		this.weight = weight;
	}
	
	public Price() {
		// TODO Auto-generated constructor stub
	}
	public Price(int num, int weight) {
		super();
		this.num = num;
		this.weight = weight;
	}
	
	
	@Override
	public String toString() {
		return "Price [num=" + num + ", weight=" + weight + "]";
	}
	
	@Override
	public int compareTo(Object o) {
		return comparator.compare(this, o);
	}
	
	
}

6、Sorter

public class Sorter {

	public static void sort(Object[] os){
		int length = os.length;
		for(int i = length ; i > 0 ; --i){
			for(int j = 0 ; j < i-1 ; ++j){
				MyComparable c1 = (MyComparable) os[j];
				MyComparable c2 = (MyComparable) os[j+1];
				
				if(c1.compareTo(c2) == 1){
					swap(os, j, j+1);
				}
			}
		}
	}
	
	public static void swap(Object[] os ,int i,int j){
		Object temp = os[i];
		os[i] = os[j];
		os[j] = temp;
	}
	
	public static void print(Object[] os){
		int length = os.length;
		
		for(int i = 0 ; i < length ; ++i){
			System.out.print(os[i] + " ");
		}
		
		System.out.println();
	}
}


7、Main //用来测试

public class Main {

	public static void main(String[] args) {
		Price[] prices = {
			new Price(1, 1),
			new Price(2, 2),
			new Price(3, 3)
		};
		
		
		Sorter.sort(prices);
		Sorter.print(prices);
	}
}


写在最后:

设计模式是一种“把简单东西复杂化”的一种东西,其实更准确的来说,它是一种要求你在开始实现某一个具体功能之前就把相应的架构给想好的开发思路。。。。