(用到了依赖倒置原则)

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

    KeyValuePair用法(转)(2012-06-25 10:47:35) 转载▼ // 标签: keyvaluepair it   KeyValuePair C# KeyValuePair< ...

  2. rtl8723 2个 wlan

    安装8723bs.ko模块之后,生成了wlan0和wlan1,MAC地址一样. http://blog.csdn.net/djman007/article/details/46731335 解决方法: ...

  3. tcpdump教程入门

    tcpdump是一个最基本重要的网络分析工具, 掌握好这, 对于学习tcp/ip协议也是很有帮助的. 理解了tcp/ip协议栈的知识, 分析调优网络的能力才会更高. 所以使用tcpdump相比其它的工 ...

  4. JavaScript模块化开发整理

    在网上已经有很多关于模块化开发的文章了,这里还是按照自己的理解来整理一下. 随着项目文件的越来越大和需求的越来越贴近现实(我发现现在客户不如:一个领导说我要审批你们报上来的资料,系统发布以后用的还不错 ...

  5. SVN----------项目服务器上的svn客户端自动更新设置。

    1.局域网服务器上搭建了PHP项目运行的环境,然后怎么样讲根目录拉去到的项目可以随着开发人员提交的代码,自动更新成最新的代码. 2.首先将svn版本库上的代码拉取到www目录下或者你的根目录. 3.然 ...

  6. Android -- 使用ViewPager实现画廊效果

    1,今天在微信推送文章看到实现画廊效果,感觉挺不错的,就来写写试试,先来看一下效果图: 上面的效果基本上可以用两个功能点来包含:ViewPager的切换动画.ImageView的倒影的实现 嗯,先来将 ...

  7. MVC筛选自定义属性下拉表

    MVC筛选自定义属性下拉表 string CompanyId = ""; CompanyId = ManageProvider.Provider.Current().Company ...

  8. Delegate(委托与事件)

    Delegate可以当它是一个占位符,比如你在写代码的时候并不知道你将要处理的是什么.你只需要知道你将要引入的参数类型和输出类型是什么并定义它即可.这就是书本上所传达的方法签名必须相同的意思. 系统自 ...

  9. Master page and jquery

    1.download latest jqury http://jquery.com/download/ 2.download latest jquery.ui, Theme select " ...

  10. Dynamics AX 2012 R3 Demo 安装与配置 - 安装数据服务器、AOS和客户端 (Step 2)

    上一节中,Reinhard主要讲解了怎么配置安装环境,尤其是域控制器,并在域中添加了一个管理员账户 MSDynAX.NET\Reinhard ,以后的安装配置,均在该账户下进行. 现在运行 AX 20 ...