(用到了依赖倒置原则)

我们写的代码中,有的时候可能会出现根据外面给定的不同的参数在方法中根据参数实例化不同的实例,就是会根据不同的参数会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 工厂模式 抽象工厂模式的更多相关文章

  1. Java设计模式(三) 抽象工厂模式

    原创文章,同步发自作者个人博客,转载请注明出处 http://www.jasongj.com/design_pattern/abstract_factory/ 抽象工厂模式解决的问题 上文<工厂 ...

  2. Java设计模式之-----工厂模式(简单工厂,抽象工厂)

    一.工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的. 工厂模式在<Java与模式>中分为三类:1)简单工厂模式(Simple Factor ...

  3. &lt;十一&gt;读&lt;&lt;大话设计模式&gt;&gt;之抽象工厂模式

    学习设计模式有一段时间了,对设计模式有一个体会,就是没那么难.就是设计程序遵循一些原则,让代码可复用,在改动的时候不用涉及太多的类,扩展方便.抽象工厂模式名字听起来抽象.但理解起来一点也不抽象,用语言 ...

  4. Java设计模式—工厂方法模式&抽象工厂模式

    工厂方法模式与抽象工厂模式都是设计模式中重要而且常见的模式.       工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类.工厂方法使一个类的实例化延迟到其子类. 通用类图如下: 在 ...

  5. PHP设计模式(三)抽象工厂模式(Abstract Factory)

    一.什么是抽象工厂模式 抽象工厂模式的用意为:给客户端提供一个接口,可以创建多个产品族中的产品对象 ,而且使用抽象工厂模式还要满足以下条件: 系统中有多个产品族,而系统一次只可能消费其中一族产品. 同 ...

  6. Java设计模式学习笔记(四) 抽象工厂模式

    前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 1. 抽象工厂模式概述 工厂方法模式通过引入工厂等级结构,解决了简单工厂模式中工厂类职责太重的问 ...

  7. Java的设计模式(4)--抽象工厂模式

    提供一个创建一系列或相互依赖对象的接口,而无须指定他们具体的类.例如某些系统可能需要为用户提供一系列相关对象,但系统不希望用户直接使用new运算符实例化这些对象,而是应当由系统来控制这些对象的创建,否 ...

  8. 设计模式--简单工厂VS工厂VS抽象工厂

    前几天我一直在准备大学毕业生,始终绑起来,如今,终于有时间去学习设计模式.我们研究今天的话题是植物三口之家的设计模式的控制--简单工厂VS工厂VS抽象工厂. 经过细心推敲,我们不难得出:工厂模式是简单 ...

  9. Head First设计模式——简单工厂、工厂、抽象工厂

    前言:按照惯例我以Head First设计模式的工厂模式例子开始编码学习.并由简单工厂,工厂模式,抽象工厂模式依次演变,归纳他们的相同与不同. 话说Head First认为简单工厂并不是设计模式,而是 ...

  10. .Net简单工厂模式,工厂模式,抽象工厂模式实例

    1.定义   简单工厂模式:是由一个工厂对象决定创建出哪一种产品类的实例.简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现. 工厂模式:定义一个用于创建对象的接口, ...

随机推荐

  1. 关于IOS的证书、App ID、设备、Provisioning Profile详述

    首先,打开developer.apple.com ,在iOS Dev Center打开Certificates, Indentifiers & Profiles认识一下基本结构.列表就包含了开 ...

  2. 详解php的curl几个函数

    关于php的curl一系列函数,这里解释一下它们的作用. 在html中,我们可以通过form设置http的post和get提交,但假如我们获取的数据不是从html中来的,而是php脚本主动向其他服务器 ...

  3. 使用maven来管理您的java项目

    maven是一个项目管理工具,使用maven可以自动管理java项目的整个生命周期,包括编译.构建.测试.发布和报告等.在大型项目开发中,使用maven来管理是必不可少的. 一.安装maven 1.W ...

  4. 重启redis报错:Waiting for Redis to shutdown

    重启redis,发现一直报:Waiting for Redis to shutdown service redis_6379 restart Stopping ... OK (error) NOAUT ...

  5. [翻译] java NIO Channel

    原文地址:http://tutorials.jenkov.com/java-nio/channels.html JAVA NIO channels和流的概念很像,下面是他们的一些区别: 你可以对cha ...

  6. mssql手工注入及绕过术

      报错注入: - 例子:http://www.kfgtfcj.xxx.cn/lzygg/Zixun_show.aspx?id=1 [1]首先爆版本:http://www.kfgtfcj.xxx.cn ...

  7. linux 下搭建svn

    Update 程序设计中的“后悔药”——SVN 一.历史起源 1.版本控制软件   答:主要是对源代码版本进行控制与管理 2.版本控制软件起源 CVS:最早期的开源的版本控制软件(开源奇葩) VSS: ...

  8. MFC通过ODBC方式连接mysql

    一. 要安装mysql-connector-odbc驱动 二. 配置数据源 电脑的控制面板-管理工具-数据源ODBC-系统DSN-添加-选择刚刚安装的mysql odbc Driver 参考 http ...

  9. JS控制checkbox全选、取消全选、删除功能的代码贴出来。。

    function checkAll() { var code_Values = document.getElementsByTagName("input"); for(i = 0; ...

  10. javaWeb 使用 filter 处理 html 标签问题

    1.web.xml代码 <filter> <filter-name>HtmlFilter</filter-name> <filter-class>de. ...