java 策略模式缺点,浅谈策略模式的应用,ASP.NET,Java,设计模式-大喵多康BigMiao的学习笔记,博客,教程...

“面向对象编程”是对现实世界的抽象,是通过代码构建出一个虚拟的世界。在虚拟世界中有人、有物,这些人和物都被称为“对象”。虚拟世界中的对象与现实世界中的一样,人有姓名、性别、年龄等一系列属性,也有吃饭、如厕、睡眠等一系列行为。

以下我通过一些真实世界中的事例,来介绍如何使用面向对象的思想来构建一个虚拟世界中的行为,并且通过“策略模式”来实现这一行为。

19f9aabb25e08f0bb7148973087ea7b2.png

如上图所示,这是我们在现实世界中经常发生的行为,男士入男厕、女士入女厕。那么我们在“面向对象”的虚拟世界中如何实现这一行为呢?

首先通过代码建立“洗手间”和“人”这两个“类”// 洗手间

// 用于声明一切洗手间的属性和行为

public interface IWashroom

{

// TODO: 此处省略洗手间的一些属性和行为

}

// 男洗手间

// 继承“洗手间”这一接口,用于实现男洗手间独有的特性

public class MenWashroom : IWashroom

{

// TODO: 此处省略男洗手间的一些属性和行为

}

// 女洗手间

// 继承“洗手间”这一接口,用于实现女洗手间独有的特性

public class WomenWashroom : IWashroom

{

// TODO: 此处省略女洗手间的一些属性和行为

}// 人

public class Person

{

// 性别

public string Gender { get; set; }

// 年龄

public int Age { get; set; }

// 如厕

public void Goto(IWashroom washroom)

{

// 省略如厕的一些具体行为

}

}

在以上代码构建的“人”和“洗手间”的虚拟世界中,如果一个人要如厕,那么应当和真实世界中一样,男士入男厕、女士入女厕,于是我们通过以下代码来实现这一行为:

var person = GetPerson(); //这是一个人

var menWashroom = new MenWashroom(); //这是一个男洗手间

var womenWashroom = new WomenWashroom();//这是一个女洗手间

if(person.Gender == "男") //如果这是人的性别是男

{

person.Goto(menWashroom); //那么就去男洗手间

}

else if(person.Gender == "女") //如果这个人的性别是女

{

person.Goto(womenWashroom); //那么就去女洗手间

}

是不是很简单?一个虚拟世界中的“厕所行为规则”就这样建立起来了。

但文明的现实世界为了方便婴幼儿和肢体残障人士,建立了“第三卫生间”

e8e4884e82f2e0d33df09acb59725beb.png

规则一下就复杂起来了,我们来梳理一下:

1.四肢健全无残疾、可独立如厕的成年男性——男厕

2.四肢健全无残疾、可独立如厕的成年女性——女厕

3.携带无法独自如厕的未成年男童、四肢健全无残疾的成年男性、男童需如厕——第三卫生间、男厕

4.携带无法独自如厕的未成年女童、四肢健全无残疾的成年男性、女童需如厕——第三卫生间

5.携带无法独自如厕的未成年男童、四肢健全无残疾的成年女性、男童需如厕——第三卫生间

6.携带无法独自如厕的未成年女童、四肢健全无残疾的成年女性、女童需如厕——第三卫生间、女厕

7.有残疾障碍可独立如厕的成年人士——第三卫生间

8.有残疾障碍但身残志坚、可独自去普通洗手间如厕的成年男性——男厕、第三卫生间

9.有残疾障碍但身残志坚、可独自去普通洗手间如厕的成年女性——女厕、第三卫生间

以上简要梳理并不涵盖所有情况,但做为本文的示例,应该可以表达出现实世界的复杂性。

考虑到现实世界如此复杂的如厕行为规则,虚拟世界若还继续采用前文所述“男士入男厕、女士入女厕”的简要行为规则的编码设计,那么至少会有9个不同的判断语句堆叠在一起,代码的可读性和可维护性将会变的极差。所以类似这种情况,我们引入设计模式中的“策略模式”设计思想,将去每一个不同洗手间想象成为不同的策略,如下:// 人 (扩充了 携带儿童、是否残疾 两个属性)

public class Person

{

// 姓名

public string Name { get; set; }

// 性别

public string Gender { get; set; }

// 年龄

public int Age { get; set; }

// 携带的儿童

public Person Child { get; set; }

// 是否残疾

public bool IsDisability { get; set; }

}// 第三卫生间

public class ThirdWashroom : IWashroom

{

// TODO: 此处省略第三卫生间的一些属性和行为

}// 男洗手间策略

public class MenWashroomStrategy

{

private Person _Person;

private MenWashroom _MenWashroom = GetMenWashroom();

public MenWashroomStrategy(Person man)

{

_Person = man;

}

public IWashroom GetWashroom()

{

// 男士

if (_Person.Gender == "男")

{

// 未携带儿童

if (_Person.Child == null)

return _MenWashroom;

// 携带男童

else if (_Person.Child.Gender == "男")

return _MenWashroom;

}

return null;

}

}// 女洗手间策略

public class WomenWashroomStrategy

{

private Person _Person;

private WomenWashroom _WomenWashroom = GetWomenWashroom();

public WomenWashroomStrategy(Person woman)

{

_Person = woman;

}

public IWashroom GetWashroom()

{

// 女士

if (_Person.Gender == "女")

{

// 未携带儿童

if (_Person.Child == null)

return _WomenWashroom;

// 携带女童

else if (_Person.Child.Gender == "女")

return _WomenWashroom;

}

return null;

}

}// 第三卫生间策略

public class ThirdWashroomStrategy

{

private Person _Person;

private ThirdWashroom _ThirdWashroom = GetThirdWashroom();

public ThirdWashroomStrategy(Person person)

{

_Person = person;

}

public IWashroom GetWashroom()

{

// 残疾

if (_Person.IsDisability)

return _ThirdWashroom;

// 携带小孩

if (_Person.Child is not null)

return _ThirdWashroom;

return null;

}

}// 根据“人”,获取TA可以去哪种洗手间

public List GetWashrooms(Person person)

{

var washrooms = new List();

var menWashroom = new MenWashroomStrategy(person).GetWashroom();

if (menWashroom != null)

washrooms.Add(menWashroom);

var womenWashroom = new WomenWashroomStrategy(person).GetWashroom();

if (womenWashroom != null)

washrooms.Add(womenWashroom);

var thirdWashroom = new ThirdWashroomStrategy(person).GetWashroom();

if (thirdWashroom != null)

washrooms.Add(thirdWashroom);

return washrooms;

}

如此一来,可以通过GetWashrooms函数,传入“人”,从而得到TA可以去哪种洗手间。

策略模式的优点在于:

1.避免程序中大量判断语句堆叠,造成代码的易读性降低、程序难易维护

2.每个策略类的算法都是独立的,不存在不同策略之间高度耦合,符合“高内聚、低耦合”的设计思想。

3.易适应需求变更、扩展性强,在需求少量变动的情况下,找到对应的策略类进行修改、或添加新的策略类

其缺点在于:

1.所有策略都必须是事先预知的,就像前文中表达的“男洗手间、女洗手间、第三卫生间”这些都是事先预知并固定存在的,若再冒出一个“第四卫生间”,那么需要对应用程序进行改动,新增一个策略类

2.每个策略对应一个策略类,若策略无限多则不适用于策略模式

好了,策略模式介绍到这里,留下几个问题供读者思考一下:

1.策略模式的主要应用场景是什么?

2.将男女洗手间、第三卫生间内部的隔间数量纳入进来,开发一个城市智慧公厕系统,你认为要考虑哪些方面?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值