Head First 设计模式 --4 工厂模式 抽象工厂模式
(用到了依赖倒置原则)
我们写的代码中,有的时候可能会出现根据外面给定的不同的参数在方法中根据参数实例化不同的实例,就是会根据不同的参数会new出不同的实例。如果这么写了,这段代码会非常的脆弱,一旦出现新的类型,那么就需要重写将这段代码找出来添加写的new。
之前说过针对接口编程,而不是针对实现。这句话也可以理解成,代码中尽量不要出现具体的实例。能用到实例的地方,应该用超类来代替,通过多态让代码走正确的分支。
通过例子来说明(看的就是《Head First 设计模式》这本书,所有还是用书中的例子)
不用工厂模式,我们就是这么写
Pizza orderPizza(String type){
Pizaa pizza;
if (type.equals("cheese")) {
pizza = new CheesePizza();
} else if (type.equals("clam")) {
pizza = new ClamPizza();
}
pizza.prepare();
pizza.bake();
//.........
}
通过工厂模式
Pizza orderPizza(String type) {
Pizza pizza = factory.createPizze("cheese");
pizza.prepare();
pizza.bake();
// .........
return pizza;
}
class SimplePizzaFactory {
public Pizza createPizze(String type) {
Pizza pizza = null;
if (type.equals("cheese")) {
pizza = new CheesePizza();
} else if (type.equals("clam")) {
pizza = new ClamPizza();
}
return pizza;
}
}
这么一看,我们似乎什么也没干,只是将代码搬到了另外一个地方。但是注意到,修改后的方法中,没有new,以后如果有新的类型的Pizza只需要修改这段代码就可以了,orderPizza的方法不用动。工厂模式就这么简单。还有另外一种类型的工厂模式,用静态方法返回实例对象,这种叫静态工厂。
class SimplePizzaFactory {
public static Pizza createCheesePizze() {
return new CheesePizza();
}
public static Pizza createClamPizze() {
return new ClamPizza();
}
}
这就是工厂模式。其实工厂模式像是一种编程习惯。然后说一下抽象工厂模式。
抽象工厂模式的作用是建立一个产品家族的抽象类型,这个类型的子类定义了实例化实例的方法,想要获取实例,首先要实例这个类型的实例,在将这个实例传入某个工厂中。抽象工厂一般配合着工厂模式使用。抽象工厂的具体工厂通常用工厂方法创建。工厂模式的主要作用是创建类的实例,抽象工厂的作用是创建一系列的实例。
根据上面修改看一下抽象工厂的代码
interface Pizza {
public void prepare();
public void bake();
}
class NSCheesePizza implements Pizza {
@Override
public void prepare() {}
@Override
public void bake() {}
}
class NSClamPizza implements Pizza {
@Override
public void prepare() {}
@Override
public void bake() {}
}
class ChicagoCheesePizza implements Pizza {
@Override
public void prepare() {}
@Override
public void bake() {}
}
class ChicagoClamPizza implements Pizza {
@Override
public void prepare() {}
@Override
public void bake() {}
}
abstract class PizzaStore {
public Pizza orderPizza(String type) {
Pizza pizza = null;
pizza = createPizza(type);
pizza.prepare();
pizza.bake();
return pizza;
}
abstract Pizza createPizza(String type);
}
class NYPizzaStore extends PizzaStore {
@Override
Pizza createPizza(String type) {
if (type.equals("chesse")) {
return new NSCheesePizza();
}
return null;
}
}
class ChicagoPizzaStore extends PizzaStore {
@Override
Pizza createPizza(String type) {
if (type.equals("chesse")) {
return new ChicagoCheesePizza();
}
return null;
}
}
public class Test {
public static void main(String[] args) {
PizzaStore nyStore = new NYPizzaStore();
Pizza pizza = nyStore.orderPizza("cheese");
}
}
这里用到了依赖倒置原则。怎么倒置的,开始时需要制作不同的pizza,不同的具体类,这样所有的pizza店都会依赖这些具体类。于是,抽象出来了一个Pizza,这样就需要一个pizza工厂,然后所有的pizza类都依赖这样一个抽象,并且pizza店也需要这个抽象。这样我们就倒置了商店依赖具体pizza类的设计。
怎么才能避免违反依赖倒置原则:
1、变量不可以持有具体类的引用。(避免使用new)
2、不要让类派生具体类。
3、不要覆盖基类已经实现的方法。(如果覆盖了基类的方法,就说明这个类不是一个真正适合的抽象类)
Head First 设计模式 --4 工厂模式 抽象工厂模式的更多相关文章
- Java设计模式(三) 抽象工厂模式
原创文章,同步发自作者个人博客,转载请注明出处 http://www.jasongj.com/design_pattern/abstract_factory/ 抽象工厂模式解决的问题 上文<工厂 ...
- Java设计模式之-----工厂模式(简单工厂,抽象工厂)
一.工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的. 工厂模式在<Java与模式>中分为三类:1)简单工厂模式(Simple Factor ...
- <十一>读<<大话设计模式>>之抽象工厂模式
学习设计模式有一段时间了,对设计模式有一个体会,就是没那么难.就是设计程序遵循一些原则,让代码可复用,在改动的时候不用涉及太多的类,扩展方便.抽象工厂模式名字听起来抽象.但理解起来一点也不抽象,用语言 ...
- Java设计模式—工厂方法模式&抽象工厂模式
工厂方法模式与抽象工厂模式都是设计模式中重要而且常见的模式. 工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类.工厂方法使一个类的实例化延迟到其子类. 通用类图如下: 在 ...
- PHP设计模式(三)抽象工厂模式(Abstract Factory)
一.什么是抽象工厂模式 抽象工厂模式的用意为:给客户端提供一个接口,可以创建多个产品族中的产品对象 ,而且使用抽象工厂模式还要满足以下条件: 系统中有多个产品族,而系统一次只可能消费其中一族产品. 同 ...
- Java设计模式学习笔记(四) 抽象工厂模式
前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 1. 抽象工厂模式概述 工厂方法模式通过引入工厂等级结构,解决了简单工厂模式中工厂类职责太重的问 ...
- Java的设计模式(4)--抽象工厂模式
提供一个创建一系列或相互依赖对象的接口,而无须指定他们具体的类.例如某些系统可能需要为用户提供一系列相关对象,但系统不希望用户直接使用new运算符实例化这些对象,而是应当由系统来控制这些对象的创建,否 ...
- 设计模式--简单工厂VS工厂VS抽象工厂
前几天我一直在准备大学毕业生,始终绑起来,如今,终于有时间去学习设计模式.我们研究今天的话题是植物三口之家的设计模式的控制--简单工厂VS工厂VS抽象工厂. 经过细心推敲,我们不难得出:工厂模式是简单 ...
- Head First设计模式——简单工厂、工厂、抽象工厂
前言:按照惯例我以Head First设计模式的工厂模式例子开始编码学习.并由简单工厂,工厂模式,抽象工厂模式依次演变,归纳他们的相同与不同. 话说Head First认为简单工厂并不是设计模式,而是 ...
- .Net简单工厂模式,工厂模式,抽象工厂模式实例
1.定义 简单工厂模式:是由一个工厂对象决定创建出哪一种产品类的实例.简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现. 工厂模式:定义一个用于创建对象的接口, ...
随机推荐
- 采用CSS3的动态元素(动画)设计div块的层级式展现
此练习作品是为学习HTML5+CSS3而设计的(如有不好请大家批评指教~~~). 操作:当页面加载时,点击网页中的绿色块(一层),则有其他几块(二层)从其中央出现并向外延伸并旋转,点击这几块中任意一个 ...
- Java复习笔记--java中this 关键字
Java中this关键字,this可以调用类的成员变量和成员方法,this还可以调用类中的构造方法.使用这种方式值得注意的是, 只可以在无参构造方法中的第一句使用this关键字调用有参构造方法. pu ...
- PHP调用内容DES加密的SOAP接口
本文以方倍工作室优惠券接口开发为例,介绍PHP下DES加解密及SOAP接口调用的实现过程. 一.基础概念 DES全称为Data Encryption Standard,即数据加密标准,是一种使用密钥加 ...
- [原创]NDT方法在SLAM中的应用
NDT概念 正态分布变换(Normal Distribution Transformation , NDT)概率密度函数( Probability Density Function, PDF)Firs ...
- 关于HTML中标签<a>使用js的注意事项
以下两点都不可取: 1.<a href="#" onClick="popUp('http://www.baidu.com');return false;" ...
- Java 画图
package com.lf.testproxy; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; i ...
- xavante运行cgilua流程
安装软件 需要安装三个lua 库: xavante wsapi cgilua luarocks install xavante http://keplerproject.github.io/xava ...
- Saving changes is not permitted in SQL Server
From Save (Not Permitted) Dialog Box on MSDN : The Save (Not Permitted) dialog box warns you that sa ...
- JS---------IIFE(Imdiately Invoked Function Expression 立即执行的函数表达式)
+function($){}(jQuery); 今天看到js代码里面有这个格式的代码,不知道啥意思,就去查了一下,我也是js小白.首先前面的+号,这个不是固定非要写+号,只要写一级运算符都可以.目的是 ...
- JS倒计时——天时分秒
HTML代码: <div id="times_wrap" class="time_num"> 距离结束时间: <div cl ...