`

《Head First设计模式》阅读笔记.第四章

    博客分类:
  • Java
阅读更多
1.简单工厂(Simple Factory)部分

*针对接口编程可以隔离掉系统以后可能发生的一大堆改变。

*用静态方法定义的工厂被成为静态工厂,这样就不用使用创建对象的方法来实例化对象,使用方便。但是这样做的缺点是无法通过继承来改变创建方法的行为。

*简单工厂不是一种设计模式,但是它比较常用。

2.工厂方法(Factory Method)模式部分

----芝加哥风味匹萨店----
public class ChicagoPizzaStore extends PizzaStore {
    Pizza createPizza(String item) {
        if ("cheese".equals(item)) {
            return ChicagoStyleCheesePizza();
        } else if ("veggie".equals(item)) {
            return ChicagoStyleVeggiePizza();
        } else if ("clam".equals(item)) {
            return ChicagoStyleClamPizza();
        } else if ("pepperoni".equals(item)) {
            return ChicagoStylePepperoniPizza();
        } else
            return null;
    }
}

------------

----加州风味匹萨店----
public class CaliforniaPizzaStore extends PizzaStore {
    Pizza createPizza(String item) {
        if ("cheese".equals(item)) {
            return CaliforniaStyleCheesePizza();
        } else if ("veggie".equals(item)) {
            return CaliforniaStyleVeggiePizza();
        } else if ("clam".equals(item)) {
            return CaliforniaStyleClamPizza();
        } else if ("pepperoni".equals(item)) {
            return CaliforniaStylePepperoniPizza();
        } else
            return null;
    }
}

------------

*工厂方法用来处理对象的创建,并将这样的行为封装在子类中。这样,客户程序中关于超类的代码就和子类对象的创建代码解耦(Decouple)了。
工厂方法的定义:abstract Product factoryMethod(String type);

*所有工厂模式都用来封装对象的创建。

*工厂方法模式(Factory Method Pattern)通过让子类来决定该创建的对象是什么,来达到将对象的创建过程封装的目的。

*在工厂方法模式中包括创建者(Creator)类和产品(Product)类两种类型的类。

----设计谜题解答----
引用
1、与NYPizzaStore和ChicagoPizzaStore平行的是CaliforniaPizzaStore类,继承自PizzaStore类。
2、与NYStyleCheesePizza和ChicagoStyleCheesePizza平行的是CaliforniaStyleCheesePizza、CaliforniaStylePepperoniPizza、CaliforniaStyleClamPizza、CaliforniaStyleVeggiePizza类,继承自Pizza类,被CaliforniaPizzaStore类所依赖。

------------

工厂(Factory Method Pattern)方法模式:定义了一个创建对象的接口,但是由子类来决定要实例化的类是哪一个。它让类把实例化推迟到了子类。

*创建者(Creator)类实现了所有操纵产品的方法,但是不实现工厂方法。

*工厂方法模式可以和策略(Strategy)模式结合起来,在运行时动态地更换工厂类,从而创建不同的产品对象,这是简单工厂所不具有的弹性。

*工厂方法模式可以让客户在实例化对象时,只依赖接口,而不依赖具体的实现类。这符合“针对接口编程,而不是针对实现编程”的软件设计原则。

*如果类A的改变会影响到类B,那么我们说类B“依赖于”类A。

软件设计原则:要依赖抽象,不要依赖具体类。这个原则又被称为“依赖倒置原则(Dependency Inversion Principle)”。

*依赖倒置原则说明不能让高层组件依赖于底层组件,而且它们都应该依赖于抽象。

*遵循依赖倒置原则的三个指导方针:
(1)变量不可以持有具体类的引用。这可以通过使用工厂避开。
(2)不要让类派生自具体类。否则就会依赖具体类,违反了“针对接口编程,而不是针对现实编程”的软件设计原则。
(3)不要覆盖基类中已实现的方法。出现这样的情况就说明基类设计的有问题。

3.抽象工厂(Abstract Factory)模式部分

抽象工厂模式:提供一个接口,用于创建相关或者依赖对象的家族,而不需要明确指定具体类。

*抽象工厂模式是工厂方法模式的演变。工厂方法模式中,创建者只生产一种类型的产品,而抽象工厂模式中,创建者生产一组不同类型的产品。

----ChicagoPizzaIngredientFactory代码----
public class ChicagoPizzaIngredientFactory implements PizzaIngredientFactory {
    public Dough createDough() {
        return new ThickCrustDough();
    }
    
    public Sause createSause() {
        return new 	FlumTomatoSause();
    }
    
    public Cheese createCheese() {
        return new Mozzarella();
    }
    
    public Veggies[] createVeggies() {
    	return new Beggies[] {new BlackOlives(), new Spinach(), new EggPlant()};
    }
    
    public Pepperoni createPepperoni() {
        return new SlicedPepperoni();
    }
    
    public Clam createClam() {
        return new FrozenClams();
    }
}

------------

*抽象工厂(Abstract Factory)模式同时结合了工厂方法(Factory Method)模式和策略(Strategy)模式。

*工厂方法使用继承:把对象的创建委托(Delegate)给子类,让子类实现工厂方法创建对象。

*抽象工厂使用对象的组合:对象的创建被实现在工厂接口所暴露出来的方法中。

*所有工厂模式都通过减少应用程序和具体类之间的依赖来促进松耦合,即解耦(Decouple)。

4.简单工厂(Simple Factory)实例
public abstract class Car {
	protected String name;// 名称

	protected String engines;// 发动机

	protected String wheels;// 车轮

	protected String lamps;// 车灯

	public void prepare() {
		System.out.println("Preparing " + name);
		System.out.println("Get engines ready...");
		System.out.println("Get wheels ready...");
		System.out.println("Get lamps ready...");
	}

	// 组装
	public void fabricate() {
		System.out.println("Adding engines.");
		System.out.println("Adding wheels.");
		System.out.println("Adding lamps.");
	}

	// 检测
	public void detect() {
		System.out.println("Detect the car.");
	}

	public String getName() {
		return name;
	}
}

public class BmwX3Car extends Car {
	public BmwX3Car() {
		name = "BMW X3";
		engines = "One Engine";
		wheels = "Four Wheels";
		lamps = "Two Lamps";
	}
}

public class BmwX5Car extends Car {
	public BmwX5Car() {
		name = "BMW X5";
		engines = "Two Engines";
		wheels = "Four Wheels";
		lamps = "Four Lamps";
	}
}

public class BmwX7Car extends Car {
	public BmwX7Car() {
		name = "BMW X7";
		engines = "Four Engine";
		wheels = "Four Wheels and One Spare Tyre";
		lamps = "Six Lamps";
	}
}

public class SimpleCarFactory {
	// 简单工厂
	public Car createCar(String type) {
		if ("bmwx3".equals(type)) {
			return new BmwX3Car();
		} else if ("bmwx5".equals(type)) {
			return new BmwX5Car();
		} else if ("bmwx7".equals(type)) {
			return new BmwX7Car();
		} else
			return null;
	}
}

// 汽车销售店
public class CarSalesShop {
	public Car orderCar(String type) {
		SimpleCarFactory factory = new SimpleCarFactory();
		Car car = factory.createCar(type);
		car.prepare();
		car.fabricate();
		car.detect();

		System.out.println("A " + car.getName() + " car is ready.");
		return car;
	}
}


5.静态工厂实例

在上例的基础上实现:
public class StaticCarFactory {
	// 静态工厂
	public static Car createCar(String type) {
		if ("bmwx3".equals(type)) {
			return new BmwX3Car();
		} else if ("bmwx5".equals(type)) {
			return new BmwX5Car();
		} else if ("bmwx7".equals(type)) {
			return new BmwX7Car();
		} else
			return null;
	}
}


修改CarSalesShop的代码:
public class CarSalesShop {
	public Car orderCar(String type) {
		Car car = StaticCarFactory.createCar(type);// 与简单工厂的区别在这里
		car.prepare();
		car.fabricate();
		car.detect();

		System.out.println("A " + car.getName() + " car is ready.");
		return car;
	}
}


6.工厂方法(Factory Method)模式实例

在上例的基础上实现:
public class BeijingBmwX3Car extends Car {
	public BeijingBmwX3Car() {
		name = "Beijing BMW X3";
		engines = "One Engine";
		wheels = "Four Wheels";
		lamps = "Two Lamps";
	}
}

public class BeijingBmwX5Car extends Car {
	public BeijingBmwX5Car() {
		name = "Beijing BMW X5";
		engines = "Two Engines";
		wheels = "Four Wheels";
		lamps = "Four Lamps";
	}
}

public class BeijingBmwX7Car extends Car {
	public BeijingBmwX7Car() {
		name = "Beijing BMW X7";
		engines = "Four Engine";
		wheels = "Four Wheels and One Spare Tyre";
		lamps = "Six Lamps";
	}
}

public class ShanghaiBmwX3Car extends Car {
	public ShanghaiBmwX3Car() {
		name = "Shanghai BMW X3";
		engines = "One Engine";
		wheels = "Four Wheels";
		lamps = "Two Lamps";
	}
}

public class ShanghaiBmwX5Car extends Car {
	public ShanghaiBmwX5Car() {
		name = "Shanghai BMW X5";
		engines = "Two Engines";
		wheels = "Four Wheels";
		lamps = "Four Lamps";
	}
}

public class ShanghaiBmwX7Car extends Car {
	public ShanghaiBmwX7Car() {
		name = "Shanghai BMW X7";
		engines = "Four Engine";
		wheels = "Four Wheels and One Spare Tyre";
		lamps = "Six Lamps";
	}
}

public abstract class CarSalesShop {
	public Car orderCar(String type) {
		Car car = createCar(type);
		car.prepare();
		car.fabricate();
		car.detect();

		System.out.println("A " + car.getName() + " car is ready.");
		return car;
	}

	// 工厂方法接口
	public abstract Car createCar(String type);
}

public class BeijingCarSalesShop extends CarSalesShop {
	@Override
	public Car createCar(String type) {
		if ("bmwx3".equals(type)) {
			return new BeijingBmwX3Car();
		} else if ("bmwx5".equals(type)) {
			return new BeijingBmwX5Car();
		} else if ("bmwx7".equals(type)) {
			return new BeijingBmwX7Car();
		} else
			return null;
	}
}

public class ShanghaiCarSalesShop extends CarSalesShop {
	@Override
	public Car createCar(String type) {
		if ("bmwx3".equals(type)) {
			return new ShanghaiBmwX3Car();
		} else if ("bmwx5".equals(type)) {
			return new ShanghaiBmwX5Car();
		} else if ("bmwx7".equals(type)) {
			return new ShanghaiBmwX7Car();
		} else
			return null;
	}
}


7.抽象工厂(Abstract Factory)模式实例
// 发动机接口
public interface Engine {
	public int getHorsepower();
}

public class BeijingEngine implements Engine {
	public int getHorsepower() {
		return 200;
	}
}

public class ShanghaiEngine implements Engine {
	public int getHorsepower() {
		return 230;
	}
}

// 车轮接口
public interface Wheel {
	public double getDiameter();
}

public class BeijingWheel implements Wheel {
	public double getDiameter() {
		return 80;
	}
}

public class ShanghaiWheel implements Wheel {
	public double getDiameter() {
		return 95;
	}
}

// 车灯接口
public interface Lamp {
	public int getPower();
}

public class BeijingLamp implements Lamp {
	public int getPower() {
		return 60;
	}
}

public class ShanghaiLamp implements Lamp {
	public int getPower() {
		return 80;
	}
}

// 汽车零件制造工厂
public interface PartsFactory {
	public Engine createEngine();

	public Wheel createWheel();

	public Lamp createLamp();
}

public class BeijingPartsFactory implements PartsFactory {
	public Engine createEngine() {
		return new BeijingEngine();
	}

	public Lamp createLamp() {
		return new BeijingLamp();
	}

	public Wheel createWheel() {
		return new BeijingWheel();
	}
}

public class ShanghaiPartsFactory implements PartsFactory {
	public Engine createEngine() {
		return new ShanghaiEngine();
	}

	public Lamp createLamp() {
		return new ShanghaiLamp();
	}

	public Wheel createWheel() {
		return new ShanghaiWheel();
	}
}

public abstract class Car {
	protected String name;// 名称

	protected Engine[] engines;// 发动机

	protected Wheel[] wheels;// 车轮

	protected Lamp[] lamps;// 车灯

	public void prepare() {
		System.out.println("Preparing " + name);
		System.out.println("Get engines ready...");
		System.out.println("Get wheels ready...");
		System.out.println("Get lamps ready...");
	}

	// 组装
	public void fabricate() {
		System.out.println("Adding engines.");
		System.out.println("Adding wheels.");
		System.out.println("Adding lamps.");
	}

	// 检测
	public void detect() {
		System.out.println("Detect the car.");
	}

	public String getName() {
		return name;
	}
}

public class BmwX3Car extends Car {
	private PartsFactory factory;

	public BmwX3Car(PartsFactory factory) {
		this.factory = factory;

		name = "BMW X3";
		// 一个发动机
		engines = new Engine[] { this.factory.createEngine() };
		// 四个车轮
		wheels = new Wheel[] { this.factory.createWheel(), this.factory.createWheel(), this.factory.createWheel(),
				this.factory.createWheel() };
		// 两个车灯
		lamps = new Lamp[] { this.factory.createLamp(), this.factory.createLamp() };
	}
}

public class BmwX5Car extends Car {
	private PartsFactory factory;

	public BmwX5Car(PartsFactory factory) {
		this.factory = factory;

		name = "BMW X5";
		// 两个发动机
		engines = new Engine[] { this.factory.createEngine(), this.factory.createEngine() };
		// 四个车轮
		wheels = new Wheel[] { this.factory.createWheel(), this.factory.createWheel(), this.factory.createWheel(),
				this.factory.createWheel() };
		// 四个车灯
		lamps = new Lamp[] { this.factory.createLamp(), this.factory.createLamp(), this.factory.createLamp(),
				this.factory.createLamp() };
	}
}

public class BmwX7Car extends Car {
	private PartsFactory factory;

	public BmwX7Car(PartsFactory factory) {
		this.factory = factory;

		name = "BMW X7";
		// 四个发动机
		engines = new Engine[] { this.factory.createEngine(), this.factory.createEngine(), this.factory.createEngine(),
				this.factory.createEngine() };
		// 四个车轮和一个备用胎
		wheels = new Wheel[] { this.factory.createWheel(), this.factory.createWheel(), this.factory.createWheel(),
				this.factory.createWheel(), this.factory.createWheel() };
		// 六个车灯
		lamps = new Lamp[] { this.factory.createLamp(), this.factory.createLamp(), this.factory.createLamp(),
				this.factory.createLamp() };
	}
}

public abstract class CarSalesShop {
	public Car orderCar(String type) {
		Car car = createCar(type);
		car.prepare();
		car.fabricate();
		car.detect();

		System.out.println("A " + car.getName() + " car is ready.");
		return car;
	}

	// 工厂方法接口
	public abstract Car createCar(String type);
}

public class BeijingCarSalesShop extends CarSalesShop {
	@Override
	public Car createCar(String type) {
		PartsFactory factory = new BeijingPartsFactory();
		if ("bmwx3".equals(type)) {
			return new BmwX3Car(factory);
		} else if ("bmwx5".equals(type)) {
			return new BmwX5Car(factory);
		} else if ("bmwx7".equals(type)) {
			return new BmwX7Car(factory);
		} else
			return null;
	}
}

public class ShanghaiCarSalesShop extends CarSalesShop {
	@Override
	public Car createCar(String type) {
		PartsFactory factory = new ShanghaiPartsFactory();
		if ("bmwx3".equals(type)) {
			return new BmwX3Car(factory);
		} else if ("bmwx5".equals(type)) {
			return new BmwX5Car(factory);
		} else if ("bmwx7".equals(type)) {
			return new BmwX7Car(factory);
		} else
			return null;
	}
}


8.结合策略模式优化抽象工厂实例

修改CarSalesShop类如下:
public class CarSalesShop {
	private PartsFactory factory;

	public CarSalesShop(PartsFactory factory) {
		this.factory = factory;
	}

	public Car orderCar(String type) {
		Car car = createCar(type);
		car.prepare();
		car.fabricate();
		car.detect();

		System.out.println("A " + car.getName() + " car is ready.");
		return car;
	}

	// 原有的工厂方法接口,现在实现了它
	public Car createCar(String type) {
		if ("bmwx3".equals(type)) {
			return new BmwX3Car(factory);
		} else if ("bmwx5".equals(type)) {
			return new BmwX5Car(factory);
		} else if ("bmwx7".equals(type)) {
			return new BmwX7Car(factory);
		} else
			return null;
	}
}


这样修改后,就不再需要BeijingCarSalesShop和ShanghaiCarSalesShop这两个类。使用方法如下:
public class Test {
	public static void main(String[] args) {
		PartsFactory factory = new BeijingPartsFactory();
		CarSalesShop shop = new CarSalesShop(factory);
		shop.orderCar("bmwx7");
	}
}


这样修改后,由于引入了策略模式,消除了两个两个子类,并且可以通过增加setPartsFactory()方法达到运行时改变零件生产工厂的目的。

--END--
7
0
分享到:
评论
1 楼 臧圩人 2010-01-14  
工厂模式很强大,很实用。

相关推荐

    笔记_HeadFirst设计模式.pdf

    笔记_HeadFirst设计模式

    Head.First 设计模式学习笔记.pdf

    ### Head.First 设计模式学习笔记知识点总结 #### 一、设计模式概述 设计模式是一种用于解决软件设计中常见问题的标准化方法。通过采用设计模式,开发者可以提高代码的复用性、灵活性和可维护性。《Head First 设计...

    HeadFirst设计模式学习笔记

    《HeadFirst设计模式学习笔记》是一份详尽的资料,旨在帮助读者深入理解并掌握设计模式这一编程领域的核心概念。设计模式是软件工程中的一种最佳实践,它在解决常见问题时提供了一种标准的解决方案,使得代码更易于...

    HeadFirst 设计模式学习笔记1--策略模式Demo

    《HeadFirst设计模式学习笔记1--策略模式Demo》 在软件工程中,设计模式是一种解决常见问题的标准方案,它提供了一种在特定情况下组织代码的模板。策略模式是设计模式中的一种行为模式,它允许在运行时选择算法或...

    HeadFirst 设计模式学习笔记3--装饰模式 Demo

    在“HeadFirst 设计模式学习笔记3--装饰模式 Demo”中,作者通过实例讲解了装饰模式的基本概念、结构和应用场景。这篇文章可能是从CSDN博客平台上的一个链接访问的,遗憾的是,由于我们当前无法直接访问该链接,所以...

    HeadFirst设计模式读书笔记

    HeadFirst设计模式 读书 笔记

    HeadFirst 设计模式学习笔记2--观察者模式 demo

    总的来说,HeadFirst设计模式的学习笔记2关于观察者模式的演示,旨在帮助开发者理解如何使用观察者模式来构建可扩展的系统。通过实际的代码示例,我们可以更深入地掌握这一模式,并将其应用到日常开发中,提升代码的...

    读书笔记:设计模式学习笔记和代码。《图解设计模式》《Head First 设计模式》.zip

    读书笔记:设计模式学习笔记和代码。《图解设计模式》《Head First 设计模式》

    Head First 设计模式 扫描版

    《Head First 设计模式》是软件开发领域内一本广受欢迎的书籍,由Eric Freeman、Elisabeth Robson、Bert Bates和Kathy Sierra四位作者共同撰写。这本书以其独特的视觉风格和易于理解的教学方法,深入浅出地介绍了...

    Head First设计模式读书笔记-DesignPatterns.zip

    《Head First设计模式》是一本深受开发者喜爱的设计模式学习书籍,它以易懂且生动的方式介绍了23种经典设计模式。这些模式是软件工程中经过实践验证的最佳实践,旨在提高代码的可重用性、可读性和可维护性。下面,...

    HeadFirst设计模式笔记

    《HeadFirst设计模式笔记》是深入理解软件设计思想的一份宝贵资料,主要涵盖了设计模式这一核心编程概念。设计模式是经过实践验证的解决方案模板,用于解决在软件开发中经常遇到的问题,尤其在面向对象设计中。这篇...

    Head First 设计模式学习笔记(十四)模式的组合使用

    在《Head First 设计模式学习笔记(十四)模式的组合使用》中,作者探讨了如何在实际编程中灵活地组合多种设计模式以解决复杂问题。这篇文章可能是基于《Head First 设计模式》这本书的一个章节,该书是设计模式领域...

    《Head First设计模式》读书笔记 -- (第一章)策略模式

    《Head First设计模式》是软件开发领域的一本经典著作,其深入浅出地介绍了23种设计模式。第一章主要讲解的是策略模式,这是一种行为设计模式,它使你能在运行时改变对象的行为。策略模式的核心思想是定义一系列算法...

    基于Java语言的《Head First 设计模式》学习笔记及实战练习源码

    本项目为《Head First 设计模式》的Java语言学习笔记与实战练习源码集合,包含104个文件,主要包括88个Java源文件、12个Markdown文档、3个XML配置文件及少量其他辅助文件。内容涵盖设计模式的学习笔记以及相应的代码...

    Head First Design Pattern 学习笔记

    著名的《Head First Design ...由于书本过长,整理出笔记帮助回想起设计模式。文件是docx格式,只能由OFFICE Word 2007之后的版本打开,内附Visio类图文件。本文由个人整理摘录,部分内容来自书本,仅供学习使用。

    head first 设计模式

    根据提供的信息,“Head First设计模式”是一本广受好评的设计模式书籍。虽然具体的章节内容没有给出,但从描述中得知本书的第22页至39页涵盖了重要的设计模式概念,因此我们将围绕这些页面可能涉及的设计模式进行...

    Head First Servlets & JSP 学习笔记

    以上只是《Head First Servlets & JSP》一书中的部分核心知识点,实际内容还包括过滤器、监听器、MVC设计模式、JSTL等更广泛的主题,旨在帮助读者全面理解和掌握Servlet和JSP技术。通过深入学习,开发者能够构建高效...

    head_first_servlet&jsp学习笔记

    【Servlet&JSP基础知识】 ...以上是`head_first_servlet&jsp`学习笔记的主要知识点,涵盖了Servlet和JSP的基础、Web应用架构、MVC模式、会话管理和JSP编程等多个方面,为深入理解和实践Servlet与JSP开发奠定了基础。

Global site tag (gtag.js) - Google Analytics