Head First(一)--策略模式-设计模式入门

本章会看看设计模式的用途和优点,再看一些关键的OO设计原则,通过实例来了解模式是如何运作的。

你的大脑总是渴求一些新奇的东西,它一直在搜寻、审视、期待着不寻常的事情发生,大脑的构造就是如此。正是这一点才让我们不至于固步自封,能跟着时代前进。

你的大脑怎么知道到底哪些东西重要呢?打个比方,加入你某一天外出旅行,突然一只大老虎跳到你面前,你的神经元会“点火”,情绪爆发,释放出一些化学物质。这样,大脑就知道这件事很重要。

你的大脑很想给你帮忙。它会努力地把这些显然不太重要的内容赶走,保证这些东西不去侵占本不算充足的脑力资源。这些资源最好还是用来记住确实重要的事情,比如大老虎,再比如火灾险情。

根据认知科学、神经生物学和教育心理学的最新研究,学习的途径相当丰富,绝非只是通过书本上的文字。有很多方法可以让大脑兴奋起来。

一些学习原则

看得到。图片更能让人记得住。通过图片,学习效率会更高。

采用一种针对个人的交谈式风格。学习过程中采用一种第一人称的交谈方式直接向读者讲述有关内容,而不是用一种干巴巴的语调介绍。要用通俗的语言。不要太严肃。如果你面对着这样两个人,一个是你在餐会上结识的很有意思的朋友,而另一个学究气十足,喋喋不休地对你说教,在这两个人中,你会更注意哪一个呢?

让学习的人想得更深。除非你很积极地让神经元活动起来,否则你的头脑里什么也不会发生。必须引起读者的好奇、促进、要求并鼓励读者去解决问题。得出结论、产生新的知识。为此,需要提出挑战,留下练习题和拓宽思路的问题,并要求读者完成一些实践活动,让左右脑都开动起来,而且要利用多种思维。

引起读者的注意,而且要让他一直保持注意。我们可能都有这样的体验,“我真的想把这个学会,不过看过一页之后就变得昏昏欲睡了”,你的大脑注意的是那些不一般、有意思、有些奇怪、抢眼的,意料之外的东西。学习一项有难度的新技术并不一定枯燥。如果学习过程不乏味,你的大脑很快就能学会。

影响读者的情绪。如果你解决了一个难题,学会了所有人都觉得很难得东西,或者发现了你了解的一些知识竟是那些自以为无所不能的傲慢的家伙所不知道的,此时就会有一种自豪感油然而生。

元认知:有关思考的思考

如果你是真的想学,而且像学得更快、更深入,就应该注意你怎样才能集中注意力。考虑自己是怎样思考的,并了解自己的学习方法。

我们中间大多数人长这么大可能都没有上过有关元认知或学习理论的课程。我们想学习,但是很少有人教我们怎么来学习。

想要最大程度地掌握这一本书的知识,就要让你的大脑负责起来,要求它记住这些内容。

技巧在于要让你的大脑认为你在学习的新东西确实很重要,对你的生活有很大影响。就像老虎出现在面前一样。如若不然,你将陷入旷日持久的拉锯战中,虽然你很想记住所学的新内容,但是你的大脑却会竭尽全力地把它们拒之门外。

怎样才能让你的大脑把设计模式看作是一只饥饿的大老虎呢?

这有两条路:一条比较慢,很乏味;另一条路不仅更快,还更有效。慢方法就是大量地重复。你肯定知道,如果反反复复地看到同一个东西,即使再没有意思,你也能学会并记住它。如果做了足够的重复,你的大脑就会说“尽管看上去这对他来说好像不重要,不过,既然他这样一而再、再而三地看同一个东西,那么我就假装着是很重要的。”

更快的方法是尽一切可能让大脑活动起来,特别是开动大脑来完成不同类型的活动。如何做到这一点呢?上面列出的学习原则正是一些主要的可取做法,而且经证实,它们确实有助于让你的大脑全力以赴。例如,研究表明、把文字放在所描述图片的中间(而不是放在这一页的别处,比如作为标题,或者放在正文中),这样会让你的大脑更多地考虑这些文字与图片之间有什么关系,而这就会让更多的神经元点火。让更多的神经元点火=你的大脑更有可能认为这些内容值得注意,而且很可能需要记下来。

交谈式风格也很有帮助,当人们意识到自己在与“别人”交谈,往往会更加关注,这是因为他们总是想跟上谈话的思路,并能做出适当的发言。另一方面,如果写作风格很正式,干巴巴的,你的大脑就会觉得像坐在一群人当中被动地听人做报告一样,很没意思,所以不必在意对方说的是什么,甚至可以打瞌睡。

我们是这么做的:

把文字放在图片当中。

采用重复手法,会用不同的方式,采用不同类型的媒体、运用多种思维手段来介绍同一个东西,目的是让有关内容更有可能存储在你的大脑中,而且能够在多个区域中都有容身之地。

我们会用你想不到的方式运用概念和图片,因为你的大脑喜欢新鲜玩意。在提供图和思想时,至少会含有一些情绪因素,因为如果能产生情绪反应,你的大脑就会投入更大的注意。而这会让你感觉到这些东西更有可能要被记住,其实这种感觉可能只是有点幽默,让人奇怪或者比较感兴趣而已。

我们采用了一种针对个人的交谈式风格。

这本书里,我们加入40多个实践活动,因为与单纯的阅读相比,如果能实际做点什么,你的大脑会更乐于学习,更愿意去记。

我们用了拟人的手法。在故事中,在示例中,还有在图中,你都会看到人的出现。这是因为你本身是一个人,不过,这就是原因。如果和人打交道,相对于东西而言,你的大脑会表示出更多的注意。

可以用下面的方法让你的大脑就范

1.慢一点,你理解的越多,需要记的就越少

不要光是看看而已。停下来,好好想一想。书中提出问题的时候,你不要直接去翻答案。可以假想成真的有人在问你问题。你让大脑想得越深,就越有可能学会并记住。

2.勤做练习,自己记笔记

不要只是坐在那里看着练习发呆。拿出笔来,写一写、画一画。大量研究都证实,学习过程中如果能实际动动手,将改善你的学习效果。

3.阅读“There are no Dumb Questions”部分

这些问题绝对是核心内容的一部分。千万不要跳过去。

4.上床睡觉之前不要再看别的书了,或者至少不再看其他有难度的东西

学习中有一部分是在你合上书之后完成的(特别是,要把学到的知识长久地记住,这往往无法在看书的过程中做到)。你的大脑也需要有自己的时间来再做一些处理。如果在这段处理时间内你又往大脑里灌输了新的知识,那么你刚学的一些东西就会被丢掉。

5.要喝水,而且要多喝点水

如果能够提供充足的液体,你的大脑才能有最佳表现。如果缺水(可能你觉得口渴之前,就已经缺水了),学习能力就会下降。

6.大声说出来

说话可以刺激大脑的另一部分。如果你想看懂什么,或者想更牢地记住它,就要大声说出来。更好的办法是,大声地解释给别人听。这样你会学得更快,而且可能会有一些新的认识,而这是以前光看不说的时候未曾发现的。

7.听听你的大脑怎么说

注意一下你的大脑是不是负荷太重了,如果发现自己开始浮光掠影地翻看,或者刚看的东西就忘记了,这说明你该休息一会儿了。达到某个临界点时,如果还一味地向大脑里塞,这对加快学习速度根本没有帮助,甚至还可能影响正常的学习。

8.要有点感觉

你的大脑需要知道这是很重要的东西。要真正融入到书中的故事里。为书里照片加上你自己的说明。你可能觉得一个笑话很蹩脚,不太让人满意,但这总比根本无动于衷要好。

9.设计一些东西

将学来的东西应用到新项目中,甚至重构旧项目。反正就是尽量应用知识,获取实践经验。你所需要的是一支铅笔和一个难题,试着应用数个设计模式解决这个难题。

读完第一次之后,你需要从头再读一次。

书里的实践活动不是可有可无的

这里的练习和实践活动也是本书核心内容的一部分。其中有些练习和活动有助于记忆,有些则能够帮助你理解,还有一些对于如何应用你所学的知识很有帮助。不要略过这些练习。

1 设计模式入门

使用模式最好的方式是:“把模式装进脑子里,然后在你的设计和已有的应用中,寻找何处可以使用它们。”

软件开发的一个不变真理-change。不管当初软件设计得多好,一段时间之后,总是需要成长与改变,否则软件就会“死亡”。

第一个设计原则:找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。

换句话说,如果每次新的需求一来,都会使某方面的代码发生变化,那么你就可以确定,这部分的代码需要被抽出来,和其他稳定的代码有所区分。

把会变化的部分取出并封装起来,以便以后可以轻易改动或扩充此部分,而不影响不需要变化的其他部分。

这个概念很简单,几乎是每个设计模式背后的精神所在。所有的模式都提供了一套方法让“系统中的某部分改变不会影响其他部分”。

分开变化和不会变化的部分。

第二个设计原则:针对接口编程,而不是针对实现编程。

我们利用接口代表每个行为,比方说,FlyBehavior与QuackBehavior,而行为的每个实现都将实现其中的一个接口。

这样的做法不同于以往。以前的做法是:行为来自Duck超类的具体实现,或是继承某个接口并由子类自行实现而来。这两种做法都是依赖于“实现”,我们被实现绑得死死的,没办法更改行为(除非写更多代码)。

原则与模式可以应用在软件开发生命周期的任何阶段。

定义超类:

package com.ken.first;

public abstract class Duck {

	FlyBehavior flyBehavior;
	QuackBehavior quackBehavior;

	public abstract void display();

	public void swim() {
		System.out.println("All ducks float, even decoys!");
	}

	public void performFly() {
		flyBehavior.fly();
	}

	public void performQuack() {
		quackBehavior.quack();
	}

	public void setFlyBehavior(FlyBehavior flyBehavior) {
		this.flyBehavior = flyBehavior;
	}

	public void setQuackBehavior(QuackBehavior quackBehavior) {
		this.quackBehavior = quackBehavior;
	}
}

定义需要变化的行为的接口:

package com.ken.first;

public interface FlyBehavior {
	void fly();
}
package com.ken.first;

public interface QuackBehavior {
	void quack();
}
定义行为接口的实现类:

package com.ken.first;

public class FlyWithWings implements  FlyBehavior {
	@Override
	public void fly() {
		System.out.println("I`m flying");
	}
}
package com.ken.first;

public class FlyNoWay implements FlyBehavior {
	@Override
	public void fly() {
		System.out.println("I can`t fly");
	}
}
package com.ken.first;

public class FlyRocketPowered implements FlyBehavior {
	@Override
	public void fly() {
		System.out.println("I`m flying with a rocket!");
	}
}
public class Quack implements QuackBehavior {
	@Override
	public void quack() {
		System.out.println("Quack");
	}
}
package com.ken.first;

public class MuteQuack implements QuackBehavior {
	@Override
	public void quack() {
		System.out.println("<< Silence >>");
	}
}
package com.ken.first;

public class Squeak implements QuackBehavior {
	@Override
	public void quack() {
		System.out.println("Squeak");
	}
}
定义子类:
package com.ken.first;

public class MallardDuck extends Duck {

	public MallardDuck() {
		flyBehavior = new FlyWithWings();
		quackBehavior = new Quack();
	}

	@Override
	public void display() {
		System.out.println("I`m a real Mallard Duck");
	}
}
package com.ken.first;

public class ModelDuck extends Duck {

	public ModelDuck() {
		flyBehavior = new FlyNoWay();
		quackBehavior = new Quack();
	}

	@Override
	public void display() {
		System.out.println("I`m a Model Duck");
	}
}
定义测试类:
package com.ken.first;

public class MiniDuckSimulator {
	public static void main(String[] args) {
		Duck mallard = new MallardDuck();
		mallard.performFly();
		mallard.performQuack();

		Duck model = new ModelDuck();
		model.performFly();
		model.setFlyBehavior(new FlyRocketPowered());
		model.performFly();
	}
}

“有一个”可能比“是一个”更好。

“有一个”关系相当有趣:每一个鸭子都有一个FlyBehavior和一个QuackBehavior,好将飞行和呱呱叫委托给它们代为处理。

当你将两个类结合起来使用,如同本例一样,这就是组合(composition)。这种做法和“继承”不同的地方在于,鸭子的行为不是继承来的,而是和适当的行为对象“组合”来的。

第三个设计原则:多用组合,少用继承。

上面这个例子就是策略模式(Strategy Pattern)。策略模式:定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。

设计模式让你和其他开发人员之间有共享的词汇,一旦懂得这些词汇,和其他开发人员之间沟通就很容易,也会促使那些不懂的程序员想开始学习设计模式。设计模式也可以把你的思考架构的层次提高到模式层面,而不是仅停留在琐碎的对象上。

“我们使用策略模式实现鸭子的各种行为。”这句话也就是告诉我们,鸭子的行为被封装进入一组类中,可以被轻易地扩充与改变。如果需要,甚至在运行时也可以改变行为。

我如何使用设计模式?

库与框架长久以来,一直扮演着软件开发过程的重要角色,我们从中挑选所要的组件,把它们放进合适的地方。

设计模式不会直接进入你的代码中,而是先进入你的“大脑”中。一旦你先在脑海中装入了许多关于模式的知识,就能够开始在新设计中采用它们,并当你的旧代码变得繁琐时,可用它们重做旧代码。

知道抽象、继承、多态这些概念,并不会马上让你变成好的面向对象设计者。设计大师关心的是建立弹性的设计,可以维护,可以应付变化。

建立可维护的OO系统,要诀在于随时想到系统以后可能需要的变化以及应付变化的原则。

阅读本书是,时时刻刻要思考着:模式如何仰赖基础与原则。

良好的OO设计必须具备可复用、可扩充、可维护三个特性。

模式可以被认为是历经验证的OO设计经验。

模式不是代码,而是针对设计问题的通用解决方案。你可把它们应用到特定的应用中。

模式不是被发明,而是被发现。

大多数的模式和原则,都着眼于软件变化的主题。

大多数的模式都允许系统局部改变独立于其他部分。

我们常常把系统中会变化的部分抽出来封装。

模式让开发人员之间有共享的语言,能够最大化沟通的价值。

关于策略模式,可以看看另一篇

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值