设计模式学习之工厂方法(Factory Method,创建型模式)(2)
接着上一讲中的简单工厂继续讲解,假如我们有了需要采集新的水果梨子,如果我们使用简单工厂中的方式的话,就会新增一个Pear类,然后实现Fruit类,然后修改FruitFactory类中获取实例的方法 getFruitInstance,新增了if else,这样虽然解决了问题,但是却违反了“开放封闭”的原则,那么我们该怎么解决呢?
第一步:
我们可以新增一个抽象的工厂FruitFactory接口,在该方法中有一个getFruitInstance()方法,然后新增AppleFactory类,BananaFactory类,实现getFruitInstance()方法,返回具体的实例new Apple(),new Banana()
第二步:
这样我们在调用的时候就可以通过工厂实现多态获取具体的工厂,然后通过具体的工厂实例来获取相对应的水果实例
FruitFactory appleFactory = new AppleFactory();
Fruit fruitApple = appleFactory.getFruitInstance();
fruitApple.get();
第三步:
假如我们需要采集新的水果梨子,那么我们只需要新增一个Pear类,然后实现Fruit类,再新增一个PearFactory类,实现FruitFactory接口,返回new Pear(),那么问题就不违反了“开放封闭”原则
代码如下:
Apple.java
package com.designpattern.factorymethod; public class Apple implements Fruit{
public void get(){
System.out.println("采集苹果");
}
}
Banana.java
package com.designpattern.factorymethod; public class Banana implements Fruit{
public void get(){
System.out.println("采集香蕉");
}
}
Pear.java
package com.designpattern.factorymethod; public class Pear implements Fruit { @Override
public void get() {
System.out.println("采集梨子");
} }
Fruit.java
package com.designpattern.factorymethod; public interface Fruit {
public void get();
}
AppleFactory.java
package com.designpattern.factorymethod; public class AppleFactory implements FruitFactory { @Override
public Fruit getFruitInstance() {
return new Apple();
} }
BananaFactory.java
package com.designpattern.factorymethod; public class BananaFactory implements FruitFactory { @Override
public Fruit getFruitInstance() {
return new Banana(); } }
PearFactory.java
package com.designpattern.factorymethod; public class PearFactory implements FruitFactory { @Override
public Fruit getFruitInstance() {
return new Pear(); } }
FruitFactory.java
package com.designpattern.factorymethod; public interface FruitFactory {
public Fruit getFruitInstance();
}
MainClass.java
package com.designpattern.factorymethod; public class MainClass {
public static void main(String[] args) {
FruitFactory appleFactory = new AppleFactory();
Fruit fruitApple = appleFactory.getFruitInstance();
fruitApple.get(); FruitFactory bananaFactory = new BananaFactory();
Fruit fruitBanana = bananaFactory.getFruitInstance();
fruitBanana.get(); /*
* 此时,如果我再添加新的水果,就只需要添加一个水果类和工厂类,而无需改动其他类就可以实现
*/
FruitFactory pearFactory = new PearFactory();
Fruit fruitPear = pearFactory.getFruitInstance();
fruitPear.get();
}
}
一、什么是工厂方法模式
工厂方法模式同样属于类的创建型模式又被称为多态工厂模式 。工厂方法模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。
二、工厂方法模式和简单工厂模式比较
工厂方法模式与简单工厂模式在结构上的不同不是很明显。工厂方法类的核心是一个抽象工厂类,而简单工厂模式把核心放在一个具体类上。
工厂方法模式之所以有一个别名叫多态性工厂模式是因为具体工厂类都有共同的接口,或者有共同的抽象父类。
当系统扩展需要添加新的产品对象时,仅仅需要添加一个具体对象以及一个具体工厂对象,原有工厂对象不需要进行任何修改,也不需要修改客户端,很好的符合了“开放-封闭”原则。而简单工厂模式在添加新产品对象后不得不修改工厂方法,扩展性不好。
工厂方法模式退化后可以演变成简单工厂模式。
设计模式学习之工厂方法(Factory Method,创建型模式)(2)的更多相关文章
- 设计模式学习心得<工厂方法 Factory Method>
概述 意图 业务代码中常常有构造对象的过程,它拥有大量的参数.并且有很多地方需要这对象. 简化对象构造过程. 主要解决 一个类在不同场景的频繁地创建,让不同对象的创建更有语义化,提高代码复用性. 何时 ...
- Factory Method(工厂方法)-对象创建型模式
1.意图 定义一个用于创建对象的接口,让子类决定实例化哪一个类.Factory Method使一个类的实例化延迟到其子类. 2.动机 框架使用抽象类定义和维护对象之间的关系.这些对象的创建通常也由框架 ...
- 抽象工厂(Abstract Factory),工厂方法(Factory Method),单例模式(Singleton Pattern)
在谈工厂之前,先阐述一个观点:那就是在实际程序设计中,为了设计灵活的多态代码,代码中尽量不使用new去实例化一个对象,那么不使用new去实例化对象,剩下可用的方法就可以选择使用工厂方法,原型复制等去实 ...
- Spring 通过工厂方法(Factory Method)来配置bean
Spring 通过工厂方法(Factory Method)来配置bean 在Spring的世界中, 我们通常会利用bean config file 或者 annotation注解方式来配置bean. ...
- 设计模式二: 工厂方法(Factory Method)
简介 工厂方法模式是创建型模式的一种, 核心结构有四个角色: 抽象工厂,具体工厂,抽象产品,具体产品; 实现层面上,该模式定义一个创建产品的接口,将实际创建工作推迟到具体工厂类实现, 一个产品对应一个 ...
- 设计模式之美:Creational Patterns(创建型模式)
创建型模式(Creational Patterns)抽象了对象实例化过程. 它们帮助一个系统独立于如何创建.组合和表示它的那些对象. 一个类创建型模式使用继承改变被实例化的类. 一个对象创建型模式将实 ...
- Java 23种设计模式详尽分析与实例解析之一--创建型模式
面向对象的设计原则 常用的面向对象设计原则包括7个,这些原则并不是独立存在的,它们相互依赖.互为补充. Java设计模式 创建型模式 简单工厂模式 模式动机: 考虑一个简单的软件应用场景,一个软件系统 ...
- [设计模式-创建型]工厂方法(Factory Method)
概括 名称 Factory Method 结构 动机 定义一个用于创建对象的接口,让子类决定实例化哪一个类.Factory Method 使一个类的实例化延迟到其子类. 适用性 当一个类不知道它所必 ...
- 设计模式——工厂方法(Factory Method)
定义一个用于创建对象的接口,让子类决定实例化哪一个类.工厂方法使一个类的实例化延迟到其子类. ——DP UML类图 模式说明 抽象业务基类 实际业务类的公共基类,也是工厂要创建的所有对象的父类,这部分 ...
随机推荐
- spring事务学习(转账案例)(一)
一.创建数据库并插入数据 create database spring_transaction; use spring_transaction; create table account( id in ...
- SQL2005删除复制数据库的发布与订阅的方法(转载)
SQL2005删除复制数据库的发布与订阅的方法 --在测试环境中恢复从正式数据库服务器 上备份下来的bak文件后,正式环境里数据库复制的发布.订阅也被带进来了,结果恢复的数据库无法更改表结构,直接删除 ...
- web.config 加密/解密
(Aspnet_regiis.exe) 这样的一个工具,可以对站点的.config文件的节进行加密 方法: #> 加密:aspnet_regiis -pef "加密的web.confi ...
- ASP.NET 5 :上传文件(转)
(此文章同时发表在本人微信公众号“dotNET每日精华文章”,欢迎右边二维码来关注.) 题记:在ASP.NET 5(MVC 6)中处理上传文件的方式和之前有所不同. 在MVC 5之前的版本中上传文件, ...
- lamp环境centos6.4
http://www.centos.bz/2011/09/centos-compile-lamp-apache-mysql-php/comment-page-1/#comments 编译安装: 首先卸 ...
- centos6.4yum搭建lamp环境
1.配置防火墙,开启80端口.3306端口vi /etc/sysconfig/iptables-A INPUT -m state --state NEW -m tcp -p tcp --dport 8 ...
- sql 联合查询并更新
update sales set sales.adminId = t.adminIdfrom (select a.adminId,a.realName from sales ,admin_admini ...
- Windows性能计数器
LogicalDisk\% Free Space 它测量选定逻辑磁盘上的可用空间百分比.请注意,如果此值低于 15%,则表示可用空间不足,操作系统无法存储关键文件.一个最直接的解决方案是增加更多的磁盘 ...
- 腾讯sdk学到了
1. 获取文本的高度和宽度 + (CGFloat)heightForContent:(MyMsgTextModel *)content withWidth:(CGFloat)width { CGSiz ...
- ios5之后arc的问题
原创: 自从ios5以后, apple官方引进了ARC (automaically reference count 自动索引计数) 这个新特性, 简单的说就是对象设置为nil(空引用)之后, 当自动索 ...