java设计模式--创建型模式(一)
2016-04-24 10:10:34
创建型模式:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式
注意:工厂模式可以分为三类: 1)简单工厂模式(Simple Factory) 2)工厂方法模式(Factory Method) 3)抽象工厂模式(Abstract Factory)
这三种模式从上到下逐步抽象,并且更具一般性。
而GOF在《设计模式》一书中将工厂模式分为两类:工厂方法模式(Factory Method)与抽象工厂模式(Abstract Factory),这是将简单工厂模式(Simple Factory)看成了工厂方法模式的一种特例,两者归为了一类。
工厂方法模式:
(1)简单工厂模式(又叫静态工厂方法模式)
通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
模式中包含的角色及其职责:
1.工厂(Creator)角色
简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类可以被外界直接调用,创建所需的产品对象。
2.抽象(Product)角色
简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。
3.具体产品(Concrete Product)角色
简单工厂模式所创建的具体实例对象
例子:采集水果,如苹果、香蕉
Apple和Banana是具体产品角色;Fruit是抽象角色,是Apple和Banana的公共接口;FruitFactory是工厂角色,负责创建Apple和Banana实例。
public interface Fruit {
/*
* 采集
*/
public void get();
}
public class Apple implements Fruit{
/*
* 采集
*/
public void get(){
System.out.println("采集苹果");
}
}
public class Banana implements Fruit{
/*
* 采集
*/
public void get(){
System.out.println("采集香蕉");
}
public class FruitFactory {
/*
* 获得Apple类的实例
*/
public static Fruit getApple() {
return new Apple();
} /*
* 获得Banana类实例
*/
public static Fruit getBanana() {
return new Banana();
}
}
public class MainClass {
public static void main(String[] args) {
Fruit apple = FruitFactory.getApple();
Fruit banana = FruitFactory.getBanana();
apple.get();
banana.get();
}
还可以如下修改FruitFactory类
public class FruitFactory {
/*
* getFruit方法,获得所有产品对象
*/
public static Fruit getFruit(String type) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
Class fruit = Class.forName(type);
return (Fruit) fruit.newInstance();
}
}
这样动态的加载和创建Class类,但是没有注意大小写;
进一步修改为:
public class FruitFactory {
/*
* getFruit方法,获得所有产品对象
*/
public static Fruit getFruit(String type) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
if(type.equalsIgnoreCase("apple")) {
return Apple.class.newInstance();
} else if(type.equalsIgnoreCase("banana")) {
return Banana.class.newInstance();
} else {
System.out.println("找不到相应的实例化类");
return null;
}
}
}
然后
public class MainClass {
public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
Fruit apple = FruitFactory.getFruit("Apple");
Fruit banana = FruitFactory.getFruit("Banana");
apple.get();
banana.get();
}
}
简单工厂模式的优缺点:
在这个模式中,工厂类是整个模式的关键所在。它包含必要的判断逻辑,能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。用户在使用时可以直接根据工厂类去创建所需的实例,而无需了解这些对象是如何创建以及如何组织的。有利于整个软件体系结构的优化。
不难发现,简单工厂模式的缺点也正体现在其工厂类上,由于工厂类集中了所有实例的创建逻辑,所以“高内聚”方面做的并不好。另外,当系统中的具体产品类不断增多时,可能会出现要求工厂类也要做相应的修改,扩展性并不很好。例如增加一种水果-梨子,需要在FruitFactory中继续增加else if语句,不符合开放封闭原则。这时候考虑下面的工厂方法模式。
(2)工厂方法模式(又叫多态工厂模式)
工厂方法模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。
模式中包含的角色及其职责:
1.抽象工厂(Creator)角色
工厂方法模式的核心,任何工厂类都必须实现这个接口。
2.具体工厂( Concrete
Creator)角色
具体工厂类是抽象工厂的一个实现,负责实例化产品对象。
3.抽象(Product)角色
工厂方法模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。
4.具体产品(Concrete Product)角色
工厂方法模式所创建的具体实例对象
例子:采集水果,如苹果、香蕉、梨子
Apple、Banana、Pear是具体产品角色;Fruit是抽象角色,是Apple、Banana、Pear的公共接口。他们的构造和前面简单工厂模式中一样。
AppleFactory、BananaFactory、PearFactory是具体工厂角色,负责创建Apple、Banana、Pear的实例;FruitFactory是抽象工厂角色,是AppleFactory、BananaFactory、PearFactory的公共接口。
public interface FruitFactory {
//水果厂
public Fruit getFruit(); }
public class AppleFactory implements FruitFactory {
//苹果厂,返回苹果实例
public Fruit getFruit() {
return new Apple();
}
}
public class BananaFactory implements FruitFactory {
//香蕉厂,返回香蕉实例
public Fruit getFruit() {
return new Banana();
}
}
public class PearFactory implements FruitFactory {
//梨子厂,返回梨子实例
public Fruit getFruit() {
return new Pear();
}
}
public class MainClass {
public static void main(String[] args) {
//获得AppleFactory
FruitFactory ff = new AppleFactory();
//通过AppleFactory来获得Apple实例对象
Fruit apple = ff.getApple();
apple.get(); //获得BananaFactory
FruitFactory ff2 = new BananaFactory();
//通过BananaFactory来获得Banana实例对象
Fruit banana = ff2.getBanana();
banana.get(); //获得PearFactory
FruitFactory ff3 = new PearFactory();
//通过PearFactory来获得Pear实例对象
Fruit pear = ff3.getPear();
pear.get();
}
}
和简单工厂模式比较:工厂方法类的核心是一个抽象工厂类,而简单工厂模式把核心放在一个具体类上。
工厂方法模式之所以有一个别名叫多态性工厂模式是因为具体工厂类都有共同的接口,或者有共同的抽象父类。
当系统扩展需要添加新的产品对象时,仅仅需要添加一个具体对象以及一个具体工厂对象,原有工厂对象不需要进行任何修改,也不需要修改客户端,很好的符合了“开放-封闭”原则。而简单工厂模式在添加新产品对象后不得不修改工厂方法,扩展性不好。工厂方法模式退化后可以演变成简单工厂模式。
抽象工厂模式
抽象工厂模式是所有形态的工厂模式中最为抽象和最其一般性的。抽象工厂模式可以向客户端提供一个接口,使得客户端在不必指定产品的具体类型的情况下,能够创建多个产品族的产品对象。
Apple、Pear属于产品等级结构;Apple又分南方Apple和北方Apple;Pear也分南方Pear和北方Pear。
一个工厂负责生产南方的Apple、Pear,这是一个产品族;一个工厂负责生产北方的Apple、Pear,这是另一个产品族。
模式中包含的角色及其职责:
1.抽象工厂(Creator)角色
抽象工厂模式的核心,包含对多个产品结构的声明,任何工厂类都必须实现这个接口。
2.具体工厂( Concrete Creator)角色
具体工厂类是抽象工厂的一个实现,负责实例化某个产品族中的产品对象。
3.抽象(Product)角色
抽象模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。
4.具体产品(Concrete Product)角色
抽象模式所创建的具体实例对象
注意:抽象工厂中方法对应产品结构,具体工厂对应产品族。
FruitFactory是抽象工厂角色,里面声明了苹果和梨子;SouthFactory和NorthFactory是具体工厂角色,SouthFactory返回南方苹果和梨子实例,NorthFactory返回北方苹果和梨子实例。
public interface Fruit {
/*
* 采集
*/
public void get();
}
public abstract class Apple implements Fruit{
/*
* 采集苹果
*/
public abstract void get();
}
public abstract class Pear implements Fruit{
/*
* 采集梨子
*/
public abstract void get();
}
public class SouthApple extends Apple { public void get() {
System.out.println("采集南方苹果");
} }
public class NorthApple extends Apple { public void get() {
System.out.println("采集北方苹果");
} }
public class SouthPear extends Pear { public void get() {
System.out.println("采集南方梨子");
} }
public class NorthPear extends Pear { public void get() {
System.out.println("采集北方梨子");
} }
public interface FruitFactory {
//实例化Apple
public Fruit getApple();
//实例化Pear
public Fruit getPear();
}
public class SouthFruitFactory implements FruitFactory { public Fruit getApple() {
return new SouthApple();
} public Fruit getPear() {
return new SouthPear();
} }
public class NorthFruitFactory implements FruitFactory { public Fruit getApple() {
return new NorthApple();
} public Fruit getPear() {
return new NorthPear();
} }
public class MainClass {
public static void main(String[] args) {
FruitFactory ff = new NorthFruitFactory();
Fruit apple = ff.getApple();
apple.get(); Fruit banana = ff.getPear();
pear.get(); FruitFactory ff2= new SouthFruitFactory();
Fruit apple2 = ff2.getApple();
apple2.get(); Fruit banana2 = ff2.getPear();
pear2.get();
}
}
如果再增加一个产品族:温室水果,包括温室苹果和温室梨子,只要增加相应的温室苹果类、温室梨子类和温室工厂类,符合“开放-封闭“”原则。但是若增加的是一个产品,如香蕉,则会违反该原则。
补充:工厂模式在开发中的应用
一个简单的计算器(主要是加法运算):
OperationFactory是抽象工厂类,AddOperationFactory是具体工厂类;Operation是抽象角色类;AddOperation和SubtractionOperation是具体角色类。
public abstract class Operation {
private double num1;
private double num2; public double getNum1() {
return num1;
} public void setNum1(double num1) {
this.num1 = num1;
} public double getNum2() {
return num2;
} public void setNum2(double num2) {
this.num2 = num2;
} public abstract double getResult();
}
public class AddOperation extends Operation { public double getResult() {
double result = this.getNum1() + this.getNum2();
return result;
}
}
public class SubtractionOperation extends Operation { public double getResult() {
double result = this.getNum1() - this.getNum2();
return result;
} }
public interface OperationFactory {
public Operation getOperation();
}
public class AddOperationFactory implements OperationFactory{ public Operation getOperation() {
return new AddOperation();
} }
import java.util.Scanner; public class MainClass {
public static void main(String[] args) {
//1.接受控制台输入
System.out.println("---计算器程序---");
System.out.println("输入第一个操作数");
Scanner scanner = new Scanner(System.in);
String strNum1 = scanner.nextLine(); System.out.println("输入运算符");
String oper = scanner.nextLine(); System.out.println("输入第二个操作数");
String strNum2 = scanner.nextLine();
double result = 0;
double num1 = Double.parseDouble(strNum1);
double num2 = Double.parseDouble(strNum2); //2.进行运算
if("+".equals(oper)) {
OperationFactory factory = new AddOperationFactory();
Operation operation = factory.getOperation();
operation.setNum1(num1);
operation.setNum2(num2);
result = operation.getResult();
} //3.返回结果
System.out.println(strNum1 + oper + strNum2 + "=" + result);
}
java设计模式--创建型模式(一)的更多相关文章
- java设计模式--创建型模式--抽象工厂
什么是抽象工厂,再次学习. 抽象工厂 概述 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 适用性 1.一个系统要独立于它的产品的创建.组合和表示时. 2.一个系统要由多个产品系 ...
- C#设计模式-创建型模式(转)
一.简单工厂模式 简单工厂模式Simple Factory,又称静态工厂方法模式.它是类的创建模式.是由一个工厂对象决定创建出哪一种产品类的实例,是不同的工厂方法模式的一个特殊实现. 优点: u 模式 ...
- C# 设计模式·创建型模式
面试问到这个··答不出来就是没有架构能力···这里学习一下···面试的时候直接让我说出26种设计模式··当时就懵逼了··我记得好像之前看的时候是23种的 还有3个是啥的··· 这里先列出几种创建型模式 ...
- java设计模式5--原型模式(Prototype)
本文地址:http://www.cnblogs.com/archimedes/p/java-prototype-pattern.html,转载请注明源地址. 原型模式 用原型实例指定创建对象的种类,并 ...
- Java设计模式——行为型模式
行为型模式,共11种:策略模式.模板方法模式.观察者模式.迭代子模式.责任链模式.命令模式.备忘录模式.状态模式.访问者模式.中介者模式.解释器模式. 11种模式的关系: 第一类:通过父类与子类的关系 ...
- java设计模式--行为型模式--状态模式
什么是行为型模式,小编觉得就是对行为的一种描述啦,一种对某种行为模型的定义. 状态模式: 状态模式 概述 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被 ...
- 设计模式-创建型模式,python享元模式 、python单例模式(7)
享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能.这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式. 享元模式尝 ...
- 设计模式----创建型模式之工厂模式(FactoryPattern)
工厂模式主要分为三种简单工厂模式.工厂方法模式.抽象工厂模式三种.顾名思义,工厂主要是生产产品,作为顾客或者商家,我们不考虑工厂内部是怎么一个流程,我们要的是最终产品.将该种思路放在我们面向对象开发实 ...
- 【C#设计模式——创建型模式】简单工场模式
进入码农行列也有一年半载了,仍然感觉自己混混沌沌,无所事事,无所作为,,,想想都下气,下气归下气,仍要奋起潜行,像愤怒的小鸟一边又一遍的冲向猪头也好,像蜗牛一样往前蹭也罢,总之要有蚂蚁啃骨头的精神!! ...
随机推荐
- postgresql数据库常用命令
--获取数据库软件版本select version();--获取数据库启动时间select pg_postmaster_start_time();--获取配置文件最近load时间select pg_c ...
- Python将列表作为栈和队列
Collections中的各种方法 阅读目录(Content) 一.各种方法介绍 二.代码部分 回到顶部(go to top) 一.各种方法介绍 Counter 统计个数 elements mo ...
- 关于PermGen space内存溢出错误解决方法
1.参考: http://blog.csdn.net/fox009/article/details/5633007 http://hi.baidu.com/like_dark/blog/item/19 ...
- HashTable vs HashMap(三)
HashTable的应用非常广泛,HashMap是新框架中用来代替HashTable的类,也就是说建议使用HashMap,不要使用HashTable. 可能你觉得HashTable很好用,为什么不用呢 ...
- 数据库schema的简介
[参考]自百度百科 数据库中的Schema,为数据库对象的集合,一个用户一般对应一个schema. 官方定义如下: A schema is a collection of database objec ...
- POJ 3251 Big Square
A quite challenging problem,最终看了题解才写出来,惭愧 /*Sample Input 6 J*J*** ****** J***J* ****** **B*** ****** ...
- tensorflow 模型保存后的加载路径问题
import tensorflow as tf #保存模型 saver = tf.train.Saver() saver.save(sess, "e://code//python//test ...
- vue-router配置之通用路径
目的:浏览器地址栏输入了未匹配的地址时,前端控制跳转到首页index页面: 项目入口js:(一般根据项目结构不同,这个js一般取名为:app.js或者main.js) import Router fr ...
- 软工作业No.4
2048小游戏—设计开发 软件需求规格说明书 甜美女孩 2018年10月 ——————————————————————————— 文档修改记录 日期 版本 说明 作者 2018-10-18 V1. ...
- avalonJS-源码阅读(2)
上一篇文章讲述的avalon刷页面所用到的几个函数. 这篇则是主要讲avalon 对刷DOM刷出来的avalon自定义属性如何处理的. 目录[-] avalon页面处理(2)数据结构解析avalon标 ...