设计模式1:找出应用中可能需要变化之处,把它们独立出来。
2012-02-08 14:43
405 查看
前景问题:
有时,想着只需要在基类中加上自己所需要的方法,所有子类就会继承该方法。但是对代码所做的局部修改,影响层面可能不是局部。你会体会到一件事:当涉及“维护”时,为了“复用”(reuse)目的而使用继承,结局并不完美。
这时,你会考虑:利用接口如何?把自己想要添加的方法从超类中取出来,放进一个“XXXable接口”中。这么一来,只有想要实现该方法的子类才实现该接口。这样如何?这真是个超笨的注意!你没有发现这么一来重复的代码会变多吗?这其实和使用继承时无止境的覆盖不需要该方法的子类一样差劲。
思考:
我们知道,有时并非所有的子类都有我们所需要添加的方法,所以继承不是适当的解决方式。虽然接口可以解决一部分问题,但是却造成代码无法复用,这只能算是从一个噩梦跳进另一个噩梦。
如果能有一种建立软件的方法,好让我们可以用一种对既有的代码影响最小的方式来修改软件该有多好。我们可以花较小的时间重做代码,而让程序去做更酷的事情。
软件开发的一个不变真理:不管你在何处工作,构建些什么,用何种编程语言,在软件开发上,一直伴随你的那个不变真理是什么?A:不管当初软件设计得多好,一段时间后,总有需要成长与改变,否则软件就会死亡。
解决方案:
幸运的是,有一个设计原则,恰好适用于此状况。A:找出应用中可能需要变化之处,把它们独立出来,不需要和那些不需要变化的代码混在一起。换句话说,如果每次新的需求一来,都会使某个方面的代码发生变化,那么你就可以确定,这部分代码需要被抽出来,和其他稳定的代码有所区分。也可以换一中思考方式:“把会变化的部分取出来并封装起来,以便以后可以轻易地改动或扩展此部分,而不影响不需要变化的其他部分”。这样的概念很简单,几乎是每个设计模式背后的精神所在。所有的模式都提供一套方法让“系统中的某部分改变不影响其他部分”。
于是我们不打算对基类做太多处理。而为需要添加的那些方法准备各自相关的类,每一组类将实现各自的动作。从现在开始,行为们将被放在分开的类中,这个类专门提供某些行为接口的实现。这些类我们称之为“行为”类由行为类而不是由子类来是实现行为接口。这样的做法迥异与以往,以前的做法:行为来自父类的具体实现,或是继承某个接口并由子类自行实现而来。这两种做法都是依赖于“实现”,没办法更改行为。以上这些所说的其实就是第二个设计原则:针对接口编程,而不是针对实现编程。
示例:假设要开发一个鸭子游戏,游戏中出现各种鸭子,一边游泳戏水,一边呱呱叫。
1.Duck基类(Duck.java)
2.FlyBehavior接口(FlyBehavior.java)
3.两个行为是实现类
(FlyWithWings.java)
(FlyNoWay.java)
4.QuackBehavior接口(QuackBehavior.java)及三个实现类
(Quack.java)
(MuteQuack)
[/code]
(Squeak.java)
5.子类(MallardDuck)
6.输出并编译测试类(MiniDuckSimulator.java)
7.运行结果:
本文出自 “幸运的路易” 博客,请务必保留此出处http://luckylouis.blog.51cto.com/3627285/774737
有时,想着只需要在基类中加上自己所需要的方法,所有子类就会继承该方法。但是对代码所做的局部修改,影响层面可能不是局部。你会体会到一件事:当涉及“维护”时,为了“复用”(reuse)目的而使用继承,结局并不完美。
这时,你会考虑:利用接口如何?把自己想要添加的方法从超类中取出来,放进一个“XXXable接口”中。这么一来,只有想要实现该方法的子类才实现该接口。这样如何?这真是个超笨的注意!你没有发现这么一来重复的代码会变多吗?这其实和使用继承时无止境的覆盖不需要该方法的子类一样差劲。
思考:
我们知道,有时并非所有的子类都有我们所需要添加的方法,所以继承不是适当的解决方式。虽然接口可以解决一部分问题,但是却造成代码无法复用,这只能算是从一个噩梦跳进另一个噩梦。
如果能有一种建立软件的方法,好让我们可以用一种对既有的代码影响最小的方式来修改软件该有多好。我们可以花较小的时间重做代码,而让程序去做更酷的事情。
软件开发的一个不变真理:不管你在何处工作,构建些什么,用何种编程语言,在软件开发上,一直伴随你的那个不变真理是什么?A:不管当初软件设计得多好,一段时间后,总有需要成长与改变,否则软件就会死亡。
解决方案:
幸运的是,有一个设计原则,恰好适用于此状况。A:找出应用中可能需要变化之处,把它们独立出来,不需要和那些不需要变化的代码混在一起。换句话说,如果每次新的需求一来,都会使某个方面的代码发生变化,那么你就可以确定,这部分代码需要被抽出来,和其他稳定的代码有所区分。也可以换一中思考方式:“把会变化的部分取出来并封装起来,以便以后可以轻易地改动或扩展此部分,而不影响不需要变化的其他部分”。这样的概念很简单,几乎是每个设计模式背后的精神所在。所有的模式都提供一套方法让“系统中的某部分改变不影响其他部分”。
于是我们不打算对基类做太多处理。而为需要添加的那些方法准备各自相关的类,每一组类将实现各自的动作。从现在开始,行为们将被放在分开的类中,这个类专门提供某些行为接口的实现。这些类我们称之为“行为”类由行为类而不是由子类来是实现行为接口。这样的做法迥异与以往,以前的做法:行为来自父类的具体实现,或是继承某个接口并由子类自行实现而来。这两种做法都是依赖于“实现”,没办法更改行为。以上这些所说的其实就是第二个设计原则:针对接口编程,而不是针对实现编程。
示例:假设要开发一个鸭子游戏,游戏中出现各种鸭子,一边游泳戏水,一边呱呱叫。
1.Duck基类(Duck.java)
public abstract class Duck { FlyBehavior flyBehavior; QuackBehavior quackBehavior; public Duck(){ } public abstract void display(); public void performFly(){ flyBehavior.fly(); } public void performQuack(){ quackBehavior.quack(); } public void swim(){ System.out.println("All ducks float, even decoys!"); } }
2.FlyBehavior接口(FlyBehavior.java)
public interface FlyBehavior { public void fly(); }
3.两个行为是实现类
(FlyWithWings.java)
public class FlyWithWings implements FlyBehavior{ public void fly(){ System.out.println("I'm flying!"); } }
(FlyNoWay.java)
public class FlyNoWay implements FlyBehavior{ public void fly(){ System.out.println("I can't fly"); } }
4.QuackBehavior接口(QuackBehavior.java)及三个实现类
public interface QuackBehavior { public void quack(); }
(Quack.java)
public class Quack implements QuackBehavior{ public void quack(){ System.out.println("Quack"); } }
(MuteQuack)
public class MuteQuack implements QuackBehavior{ public void quack(){ System.out.println("<<Silence>>"); } }
[/code]
(Squeak.java)
public class Squeak implements QuackBehavior{ public void quack(){ System.out.println("Squeak"); } }
5.子类(MallardDuck)
public class MallardDuck extends Duck{ public MallardDuck(){ quackBehavior=new Quack(); flyBehavior=new FlyWithWings(); } public void display(){ System.out.println("I'm a real Mallard duck."); } }
6.输出并编译测试类(MiniDuckSimulator.java)
public class MiniDuckSimulator { public static void main(String[] args){ Duck mallard=new MallardDuck(); mallard.performQuack(); mallard.performFly(); mallard.display(); } }
7.运行结果:
本文出自 “幸运的路易” 博客,请务必保留此出处http://luckylouis.blog.51cto.com/3627285/774737
相关文章推荐
- 桥接模式(Bridge)将抽象部分与它的实现部分分离,使它们都可以独立地变化。
- 微服务可能应用的设计模式
- 小易邀请你玩一个数字游戏,小易给你一系列的整数。你们俩使用这些整数玩游戏。每次小易会任意说一个数字出来,然后你需要从这一系列数字中选取一部分出来让它们的和等于小易所说的数字。 例如: 如果{2,1,2,7}是你有的一系列数,小易说的数字是11.你可以得到方案2+2+7 = 11.如果顽皮的小易想坑你,他说的数字是6,那么你没有办法拼凑出和为6 现在小易给你n个数,让你找出无法从n个数中选取部分求和
- 分布式服务设计(该模式应用与所有服务器需要一份一致的内存数据时)
- 设计模式:对于一种类,有可能需要在其执行前,中,后,插入一些代码,留下接口,让调用者实现
- 策略模式(Strategy)-定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。
- 《从零开始学Swift》学习笔记(Day67)——Cocoa Touch设计模式及应用之MVC模式
- 在 Java 中应用设计模式 - Factory Method
- 设计模式-装饰者模式(问题比较大,需要重新处理)
- JAVA设计模式-策略模式应用实例
- JAVA设计模式-策略模式应用实例
- 常用设计模式的应用场景
- 设计模式学习笔记--设计模式在Java I/O中的应用(装饰模式和适配器模式)
- 《从零开始学Swift》学习笔记(Day 63)——Cocoa Touch设计模式及应用之单例模式
- 设计模式(十七)-观察者模式(Observer Pattern)——发送状态变化通知
- JSP设计模式基础:View Helper模式——学习如何使用View Helper模式使得Model数据适应表现层的需要(1)
- JAVA中数据库操作的各种方式与设计模式的应用(http://blog.csdn.net/wangyihust/archive/2006/01/14/579613.aspx)
- Java——设计模式——装饰者模式——在IO里的应用
- JAVA中数据库操作的各种方式与设计模式的应用
- 2009 年8 月6号 学习 uml、ea、设计模式以及如何使用它们进行分析、设计