Head First Design Patterns

From Head First Design Patterns.

Design Principle:

Idnetify the aspects of your application that vary and separate them from what stays the same.

Here‘s another way to think about it:

Take the parts that vary and encapsulate them, so that later you can alter or extend the parts that vary without affecting those that don‘t.


SimUDuck App

We need to separate behaviors from Duck class. So, let‘s define two behavior interfaces: QuackBehavior and FlyBehavior with additonal instantial classes.

Design Principle

Program to an interface, not an implementation.

QuackBehavior interface and instantial classes:

public interface QuackBehavior {
	public void quack();
}

public class Quack implements QuackBehavior {
	public void quack() {
		System.out.println("Quack");
	}
}

public class MuteQuack implements QuackBehavior {
	public void quack(){
		System.out.println("<< Silence >>");
	}
}

public class Squeak implements QuackBehavior {
	public void quack() {
		System.out.println("Squeak");
	}
}

FlyBehavior interface and instantial classes:

public interface FlyBehavior {
	public void fly();
}

public class FlyWithWings implements FlyBehavior {
	public void fly() {
		System.out.println("I‘m flying!!");
	}
}

public class FlyNoWay implements FlyBehavior {
	public void fly() {
		System.out.println("I can‘t fly");
	}
}

And then, we can define the abstract class Duck, which is the base class of our Duck Project:

public abstract class Duck {
	QuackBehavior quackBehavior;
	FlyBehavior flyBehavior;

	public Duck() {

	}

	public abstract void display();

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

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

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

Now, we can make a concrete duck, Mallard!

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");
	}
}

Finally,let‘s write a  simulator to test our codes:

public class MiniDuckSimulator {
	public static void main(String[] args) {
		Duck mallard = new MallardDuck();
		mallard.performQuack();
		mallard.performFly();
		mallard.display();
	}
} /* Output:
Quack
I‘m flying!!
I‘m a real Mallard duck
*/

Pay attention, the duck mallard here only offer two APIs: performQuack(), performFly(). We can‘t call quack() or fly(), which also make the process of calling behaviors simple.

It‘s a shame to have all dynamic talent built into our ducks and not be using it!

If you want to set duck‘s behavior now, you should make it through instantiating it in the duck‘s constructor rather than adding a setter method on the duck subclass.

Add two new methods to the Duck class:

public void setFlyBehavior(FlyBehavior fb) {
	flyBehavior = fb;
}

public void setQuackBehavior(QuackBehavior qb) {
	quackBehavior = qb;
}

Let‘s make a new Duck type:

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

 public void display() {
  System.out.println("I‘m a model duck");
 }
}

adding new FlyBehavior type:

public class FlyRocketPowered implements FlyBehavior {
 public void fly() {
  System.out.println("I‘m flying with a rocket!");
 }
}

Now, we can add some codes in simulator to test our set methods:

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

Here, the model duck dynamically changed its flying behavior!

You can‘t do THAT if the implementation lives inside the duck class!

Design Principle

Favor composition over inheritance.

In this project, we use the Stragegy pattern, the formal definition is:

The Strategy Pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it.

时间: 2024-10-14 12:57:04

Head First Design Patterns的相关文章

设计模式(Design Patterns)

设计模式(Design Patterns) 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性. 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样.项目中合理的运用设计模式可以完美的解决很多问题,每种模式在现在中都有相应的原理来与之对应,每一个模式描述了一个在我们周围不断重复发生的问题,以及该问

Design Patterns 5 原型模式 Prototype

原型模式 Prototype 原型模式:用原型实例指定创建对象的种类,并且通过拷贝这个原型来创建新的对象. 当我们需要多个相同的类实例时,没必要每次都使用new运算符去创建相同的类实例对象,我们可以用原型模式减少内存的消耗和达到类实例的复用. //带有返回自身接口的抽象原型类 public abstract class Prototype5 { public string Id { get; set; } public Prototype5(string id) { this.Id = id;

Cocoa Design Patterns

Book Description This is the Rough Cut version of the printed book. Much of the technology embodied by Apple's Cocoa software development frameworks have been in commercial use since 1988, and in spite of many years of use, the Cocoa frameworks are s

Learning JavaScript Design Patterns The Observer Pattern

The Observer Pattern The Observer is a design pattern where an object (known as a subject) maintains a list of objects depending on it (observers), automatically notifying them of any changes to state. When a subject needs to notify observers about s

[Design Patterns] 4. Creation Pattern

设计模式是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结,使用设计模式的目的是提高代码的可重用性,让代码更容易被他人理解,并保证代码可靠性.它是代码编制真正实现工程化. 四个关键元素:(1) Pattern Name, (2) Problem, (3) Solution, (4) Consequences. 01. Factory Method Pattern /* The product should be created by his own factory. */ Log

MapReduce Design Patterns

1. Design Patterns and MapReduce. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Design PatternsMapReduce HistoryMapReduce and Hadoop RefresherHadoop Example: Word CountPig and Hive 2. Summarization Patter

Learning JavaScript Design Patterns The Module Pattern

The Module Pattern Modules Modules are an integral piece of any robust application's architecture and typically help in keeping the units of code for a project both cleanly separated and organized. In JavaScript, there are several options for impleme

Design Patterns 4 酒干倘卖无---抽象工厂模式AbstractFactory

抽象工厂模式AbstractFactory 抽象工厂模式:提供一个创建产品的接口来负责创建相关或依赖的对象,而不具体明确指定具体类. 抽象工厂对于系列产品的变化支持 “开放——封闭”原则(指的是要求系统对扩展开放,对修改封闭),扩展起来非常简便,但对于添加新产品这种情况就不支持”开放——封闭 “原则. Design Patterns 4 酒干倘卖无---抽象工厂模式AbstractFactory,布布扣,bubuko.com

Android Design Patterns

出版时间:2013 下载地址:百度网盘 内容简介: Master the challenges of Android user interface development with these sample patterns With Android 4, Google brings the full power of its Android OS to both smartphone and tablet computing. Designing effective user interfac

Design Patterns Example Code (in C++)

Overview Design patterns are ways to reuse design solutions that other software developers have created for common and recurring problems. The design patterns on this page are from the book Design Patterns, Elements of Reusable Object-Oriented Softwa