java设计模式--三种工厂模式详解
作者:吾仄lo咚锵 发布时间:2023-11-29 09:54:06
简单工厂
简单工厂模式是属于创建型模式,是工厂模式的一种。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。定义了一个创建对象的类,由这个类来封装实例化对象的行为(代码)。当我们会用到大量的创建某种、某类或者某批对象时,就会使用到工厂模式。
由于创建实例的方法通常为静态(static)方法,因此简单工厂模式又被成为静态工厂方法模式(Static Factory Method)。
Product表示产品接口,也可用抽象类实现,封装产品间共有的属性。
ConcreteProduct*表示具体的实际产品。
Factory表示工厂,工厂根据需要来创建相应的产品。
这样一来,当添加新的产品C时,只需要修改工厂部分代码即可,而传统方法需要在每一个创建产品的地方都进行修改。可以理解为把具体的产品创建封装成一个工厂类。
举个例子,大富翁的地图创建:
AbstractBlock是接口,表示抽象的地块,包括方法printBlock()打印地块。
Empty、Prison、Park实现上述接口,表示空地(*)、监狱(&)和公园(#)。
SimpleFactory是创建地块的简单工厂。
类图:
代码:
1.产品接口
public interface AbstractBlock {
public void printBlock();
}
2.产品接口实现子类
public class Empty implements AbstractBlock{
@Override
public void printBlock() {
System.out.print("* ");
}
}
public class Park implements AbstractBlock{
@Override
public void printBlock() {
System.out.print("# ");
}
}
public class Prison implements AbstractBlock{
@Override
public void printBlock() {
System.out.print("& ");
}
}
3.简单工厂类
public class SimpleFactory {
public AbstractBlock getBlock(String type){ //根据传参创建不同的地块
if(type.equalsIgnoreCase("Empty")){
return new Empty();
} else if(type.equalsIgnoreCase("Park")){
return new Park();
} else if(type.equalsIgnoreCase("Prison")){
return new Prison();
}
return null;
}
}
4.调用工厂
public class Map {
public void getMap(){
SimpleFactory simpleFactory=new SimpleFactory(); //实例化工厂
ArrayList<AbstractBlock> map=new ArrayList<AbstractBlock>(); //地块集合
String []types=new String[3];
types[0]="Empty";
types[1]="park";
types[2]="Prison";
Random rd = new Random();
for(int i=1;i<=12;i++){ //随机用工厂创建地块并放入集合
int tt = rd.nextInt(types.length);
map.add(simpleFactory.getBlock(types[tt]));
}
//地图大小写死了,不是重点
for(int i=0;i<12;i++){
map.get(i).printBlock();
if(i==3||i==5||i==7)
System.out.println();
if(i==4||i==6)
System.out.print(" ");
}
}
}
5.测试
public class MonoPoly {
public static void main(String[] args) {
Map map=new Map();
map.getMap();
}
}
运行结果
工厂方法
不难发现,当增加新的产品时需要对简单工厂类修改,或创建多个简单工厂。(比如增加一个法院地块)工厂方法进一步解耦合,把工厂类抽象,不再负责所有实例的创建,而是把具体的创建工作交给了子类去完成,实例化延迟到子类加载,由子类来决定要实例化的类。
抽象化工厂类,把具体实例化工作交给其子类实现。
代码:
1.工厂接口
public interface AbstractFactory {
public AbstractBlock createBlock();
}
2.工厂实现子类
public class EmptyFactory implements AbstractFactory {
@Override
public AbstractBlock createBlock() {
return new Empty();
}
}
public class ParkFactory implements AbstractFactory {
@Override
public AbstractBlock createBlock() {
return new Park();
}
}
public class PrisonFactory implements AbstractFactory {
@Override
public AbstractBlock createBlock() {
return new Prison();
}
}
3.产品接口
public interface AbstractBlock {
public void printBlock();
}
4.产品实现子类
public class Empty implements AbstractBlock {
@Override
public void printBlock() {
System.out.print("* ");
}
}
public class Park implements AbstractBlock {
@Override
public void printBlock() {
System.out.print("# ");
}
}
public class Prison implements AbstractBlock {
@Override
public void printBlock() {
System.out.print("& ");
}
}
5.调用
public class Map {
public void getMap() {
ArrayList<AbstractBlock> map=new ArrayList<AbstractBlock>(); //地块集合
AbstractFactory abstractFactory;
Random rd = new Random();
for(int i=1;i<=12;i++){ //随机用工厂创建地块并放入集合
int tt = rd.nextInt(3);
if(tt==0)abstractFactory=new EmptyFactory();
else if(tt==1)abstractFactory=new ParkFactory();
else abstractFactory=new PrisonFactory();
map.add(abstractFactory.createBlock());
}
//地图大小写死了,不是重点
for(int i=0;i<12;i++){
map.get(i).printBlock();
if(i==3||i==5||i==7)
System.out.println();
if(i==4||i==6)
System.out.print(" ");
}
}
}
6.测试
public class MonoPoly {
public static void main(String[] args) {
Map map=new Map();
map.getMap();
}
}
运行结果:
抽象工厂
不难发现当创建新的产品接口时,也需要对工厂方法修改,或创建多个工厂方法。(比如增加魔法地块簇,对应组产品魔法公园、魔法空地、魔法监狱等)
抽象工厂将工厂方法进一步抽象。定义了一个接口用于创建相关或有依赖关系的对象簇,而无需指明具体的类。可以根据创建对象类型使用对应的工厂子类。这样将单个的简单工厂类变成了工厂簇,更利于代码的维护和扩展。
把工厂类抽象后,对应不同子类工厂(普通/魔法),生产对应的一组产品。最后调用时统一调用抽象接口即可,不必知道具体对象,面向接口编程。
1.产品接口
public interface AbstractBlock {
void printBlock();
}
2.产品抽象子类-普通产品
public abstract class NormalAbstractBlock implements AbstractBlock {
public abstract void printBlock();
}
2.2普通空地
public class NormalEmpty extends NormalAbstractBlock {
public void printBlock() {
System.out.print("* ");
}
}
2.3普通公园
public class NormalPark extends NormalAbstractBlock {
public void printBlock() {
System.out.print("# ");
}
}
2.4普通监狱
public class NormalPrison extends NormalAbstractBlock {
public void printBlock() {
System.out.print("& ");
}
}
3.1产品抽象子类-魔法产品
public abstract class MagicAbstractBlock implements AbstractBlock {
public abstract void printBlock();
}
3.2魔法空地
public class MagicEmpty extends MagicAbstractBlock {
public void printBlock() {
System.out.print("e ");
}
}
3.3魔法公园
public class MagicPark extends MagicAbstractBlock {
public void printBlock() {
System.out.print("g ");
}
}
3.4魔法监狱
public class MagicPrison extends MagicAbstractBlock {
public void printBlock() {
System.out.print("p ");
}
}
4.工厂接口
public interface AbstractFactory {
AbstractBlock getEmpty();
AbstractBlock getPrison();
AbstractBlock getPark();
}
5.工厂实现子类-普通工厂
public class NormalFactory implements AbstractFactory {
public AbstractBlock getEmpty() { return new NormalEmpty(); }
public AbstractBlock getPrison() { return new NormalPrison(); }
public AbstractBlock getPark() { return new NormalPark(); }
}
6.工厂实现子类-魔法工厂
public class MagicFactory implements AbstractFactory {
public AbstractBlock getEmpty() { return new MagicEmpty(); }
public AbstractBlock getPrison() {return new MagicPrison(); }
public AbstractBlock getPark() { return new MagicPark(); }
}
7.调用
public class Map {
public void getMap(AbstractFactory af){
ArrayList<AbstractBlock> map=new ArrayList<AbstractBlock>();
map.add(af.getEmpty());
map.add(af.getPrison());
map.add(af.getPark());
Random rd = new Random(3);
int col=12;
for(int i=1;i<=col;i++){
int tt = rd.nextInt(3);
map.get(tt).printBlock();
if(i==4||i==6||i==8)
System.out.println();
if(i==5||i==7)
System.out.print(" ");
}
}
}
8.测试
public class Monopoly {
public void play(){
Map map=new Map();
Scanner scan = new Scanner(System.in);
System.out.println("请输入指令(1输出普通地图,2输出魔法地图)");
int order;
order = scan.nextInt();
if(order == 1){
map.getMap(new NormalFactory());
}else{
map.getMap(new MagicFactory());
}
}
}
运行结果:
来源:https://wzlodq.blog.csdn.net/article/details/110143303
猜你喜欢
- 在使用 springboot 或者 springcloud 开发的时候,通常为了保证系统的安全性,配置文件中的密码等铭感信息都会进行加密处理
- 什么是继承面向对象的特征:封装:不必要公开的数据成员和方法,使用private关键字进行修饰。意义:安全性。背景代码中创建的类, 主要是为了
- 1、说明isInterrupted()可以判断当前线程是否被中断,仅仅是对interrupt()标识的一个判断,并不会影响标识发生任何改变(
- 定义:用于顺序访问集合对象的元素,不需要知道集合对象的底层表示。特点: 1、它支持以不同的方式遍历一个
- 本文实例讲述了Java实现特定范围的完数输出算法。分享给大家供大家参考,具体如下:题目内容:一个正整数的因子是所有可以整除它的正整数。而一个
- 使用场景EntityListeners在jpa中使用,如果你是mybatis是不可以用的它的意义对实体属性变化的跟踪,它提供了保存前,保存后
- Handler每个初学Android开发的都绕不开Handler这个“坎”,为什么说是个坎呢,首先这是Android架构的精髓之一,其次大部
- 背景大家在使用Selenium + Chromedriver爬取网站信息的时候,以为这样就能做到不被网站的反爬虫机制发现。但是实际上很多参数
- intellij idea是一款非常优秀的软件开发工具,它拥有这强大的插件体系,可以帮助开发者完成很多重量级的功能。今天,我们来学习一下如何
- 首先给出一段代码:public class AslistMethod { public static void main(String[]
- 这段时间用到了QT的TCP通信,做了初步的学习与尝试,编写了一个客户端和服务器基于窗口通信的小例程。使用QT的网络套接字需要.pro文件中加
- 一、使用Optional引言1.1、代码问题引出在写程序的时候一般都遇到过 NullPointerException,所以经常会对程序进行非
- 最近碰到这么个恶心的问题问题:有个arr文件被放到Module A中引用,现在Module B又依赖了Module A,则在编译过程中会发生
- java arrayList遍历的四种方法及Java中ArrayList类的用法package com.test;import java.u
- mybatis if test判断入参的值1.第一种判断方式<if test=' requisition != null an
- 一、项目要求实现一个通讯录通讯录可以用来存储100个人的信息,每个人的信息包括:姓名、性别、年龄、电话、住址提供方法:添加联系人信息删除指定
- 众所周知Java中的数据类型是强数据类型,基本数据类型之间的转换尤其固定的规则,当数据宽度比较窄的数据类型(如int)转换成数据类型比较宽的
- File类简介package com.file;import java.io.File;import java.io.IOException
- 什么是注解在早期的工作的时候 ,自定义注解写的比较多,可大多都只是因为 这样看起来 不会存在一堆代码耦合在一起的情况,所以使用了自定义注解,
- 对接支付宝支付接口,官方文档已经写的很清楚了,但是也有很多像我一样的小白,第一次对接支付宝支付接口,会有些迷茫,所以我在此写下这篇文章,给我