(用到了依赖倒置原则)

我们写的代码中,有的时候可能会出现根据外面给定的不同的参数在方法中根据参数实例化不同的实例,就是会根据不同的参数会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. toggle函数

    $(function() { $('.love').toggle(function() { $(this).attr("src", "images/loved.png&q ...

  2. Synchronized 个人深解

      1.synchronized方法相当于synchronized(this)      Synchronized 方法是锁的当前对象,同一个对象的2个synchronized方法被2个线程调用会发生 ...

  3. sql操作之修改记录值

    mysql修改.删除数据记录 用update修改记录 UPDATE tbl_name SET 要更改的列 WHERE 要更新的记录 这里的 WHERE 子句是可选的,因此如果不指定的话,表中的每个记录 ...

  4. echo 输入指定空白字符

    ansible-direc:~ # echo -n "starting service....";echo -ne "\033[50G";echo " ...

  5. Linux:安装OpenSSH-Server E:Package openssh-server has no installation candidate

    $sduo apt-get install openssh-server Reading package lists… Done Building dependency tree Reading st ...

  6. NRF905 无线模块实验

    ---恢复内容开始--- 采用2440开发板,CON4 不仅包含了很多富余的 GPIO 引脚,还包含了一些其他 CPU 引脚, 如 AD0-AIN3, CLKOUT 等.你所看到的图中的 SPI 接口 ...

  7. Zabbix通过percona监控MySQL

    因为Zabbix自带的MySQL监控没有提供可以直接使用的Key,所以一般不采用,业界的同学们都使用Percona Monitoring Plugins 监控 MySQL的方式 Percona介绍 P ...

  8. sdutoj 2609 A-Number and B-Number

    http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2609 A-Number and B-Numbe ...

  9. windows系统调用 获取当前内存信息

    #include "iostream" #include "windows.h" #include "shlwapi.h" #include ...

  10. 夺命雷公狗-----React---5--props对象的传递

    提示:props的值是不可以改变的... <!DOCTYPE html> <html lang="en"> <head> <meta ch ...