创建具体的产品,并继承产品抽象类
工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。
PS:在设计模式中,“实现一个接口”泛指实现某个超类型(可以是类或接口)的某个方法。
要点:
- 通过子类来创建具体的对象。客户只需要知道他们所使用的抽象类型即可。
- 由子类决定要实例化的类是哪一个,是指在编写创建者类时,不需要知道实际创建的产品是哪一个。选择了使用哪个创建者子类,自然就决定了实际创建的产品是什么。
- 对象统一由定义好的工厂方法来创建。
二、实现步骤
1、创建产品抽象类
/*** 产品抽象类*/
public abstract class Product {String name;public String getName() {return name;}
}
2、创建具体的产品,并继承产品抽象类
(1)产品A1
/*** 产品A1*/
public class ConcreteProductA1 extends Product {public ConcreteProductA1() {name = "ConcreteProductA1";}
}
(2)产品A2
/*** 产品A2*/
public class ConcreteProductA2 extends Product {public ConcreteProductA2() {name = "ConcreteProductA2";}
}
(3)产品B1
/*** 产品B1*/
public class ConcreteProductB1 extends Product {public ConcreteProductB1() {name = "ConcreteProductB1";}
}
(4)产品B2
/*** 产品B2*/
public class ConcreteProductB2 extends Product {public ConcreteProductB2() {name = "ConcreteProductB2";}
}
3、创建创建者抽象类,并定义用来创建产品的工厂方法
创建者一般为需要用到产品的类,需要的产品则通过类中的工厂方法创建。
/*** 创建者抽象类*/
public abstract class Creator {/*** 创建产品(工厂方法)*/protected abstract Product createProduct(String productType);
}
4、创建具体的创建者,并继承创建者抽象类
具体的创建者需要实现创建产品的工厂方法。
(1)创建者1
/*** 创建者1*/
public class ConcreteCreator1 extends Creator {@Overrideprotected Product createProduct(String productType) {// 由具体的创建者(子类)决定创建哪个类的对象if ("A".equals(productType)) {return new ConcreteProductA1();} else if ("B".equals(productType)) {return new ConcreteProductB1();}return null;}
}
(2)创建者2
/*** 创建者2*/
public class ConcreteCreator2 extends Creator {@Overrideprotected Product createProduct(String productType) {// 由具体的创建者(子类)决定创建哪个类的对象if ("A".equals(productType)) {return new ConcreteProductA2();} else if ("B".equals(productType)) {return new ConcreteProductB2();}return null;}
}
5、创建者通过工厂方法创建产品
public class Test {public static void main(String[] args) {// 创建者1Creator creator1 = new ConcreteCreator1();// 创建者2Creator creator2 = new ConcreteCreator2();// 通过工厂方法创建产品Product product = creator1.createProduct("A");System.out.println("创建者1创建产品A:" + product.getName());product = creator2.createProduct("A");System.out.println("创建者2创建产品A:" + product.getName());}
}
三、举个栗子
1、背景
假设你有一个披萨店,出售多种类型的披萨:芝士披萨、蛤蜊披萨、素食披萨等。由于经营有成,你打算推广自己的加盟店。
为了确保加盟店运营的质量,你希望加盟店能够采用固定的制作流程。但是由于区域的差异,每家加盟店都可能想要提供不同风味的披萨(比如纽约、芝加哥、加州),因此又必须允许加盟店能够自由地制作该区域的风味。
2、实现
披萨店子类通过实现创建披萨方法来决定要创建什么风味的披萨。
(1)创建披萨抽象类
/*** 披萨抽象类*/
public abstract class Pizza {/*** 名称*/String name;/*** 面团*/String dough;/*** 酱料*/String sauce;/*** 佐料*/ArrayList<String> toppings = new ArrayList<>();void prepare() {System.out.println("Preparing " + name);System.out.println("Tossing dough...");System.out.println("Adding souce...");System.out.println("Adding toppings: ");for (int i = 0; i < toppings.size(); i++) {System.out.println(" "+ toppings.get(i));}}/*** 烘烤*/void bake() {System.out.println("Bake for 25 minutes at 350");}/*** 切片*/void cut() {System.out.println("Cutting the pizza into diagonal slices");}/*** 装盒*/void box() {System.out.println("Place pizza in official PizzaStore box");}public String getName() {return name;}
}
(2)创建不同风味、不同类型的披萨
/*** 纽约风味的芝士披萨*/
public class NYStyleCheesePizza extends Pizza {public NYStyleCheesePizza() {name = "NY Style Sauce and Cheese Pizza";dough = "Thin Crust Dough";sauce = "Marinara Sauce";toppings.add("Grated Reggiano Cheese");}
}
/*** 纽约风味的蛤蜊披萨*/
public class NYStyleClamPizza extends Pizza {public NYStyleClamPizza() {name = "NY Style Sauce Clam Pizza";dough = "Thin Crust Dough";sauce = "Marinara Sauce";toppings.add("Fresh Clams");}
}
/*** 芝加哥风味的芝士披萨*/
public class ChicagoStyleCheesePizza extends Pizza {public ChicagoStyleCheesePizza() {name = "Chicago Style Deep Dish Cheese Pizza";dough = "Extra Thick Crust Dough";sauce = "Plum Tomato Sauce";toppings.add("Shredded Mozzarella Cheese");}void cut() {System.out.println("Cutting the pizza into square slices");}
}
/*** 芝加哥风味的蛤蜊披萨*/
public class ChicagoStyleClamPizza extends Pizza {public ChicagoStyleClamPizza() {name = "Chicago Style Clam Pizza";dough = "Extra Thick Crust Dough";sauce = "Plum Tomato Sauce";toppings.add("Frozen Clams");}void cut() {System.out.println("Cutting the pizza into square slices");}
}
(3)创建披萨店抽象类
/*** 披萨店抽象类*/
public abstract www.xingyunylpt.com class PizzaStore {/*** 订购披萨*/public Pizza www.youy2zhuce.cn orderPizza(String type) {Pizza pizza www.jujinyule.com= createPizza(type);pizza.prepare( www.shentuylgw.cn);pizza.bake(www.lanboyulezc.cn);pizza.cut( www.tengyao3zc.cn);pizza.box(www.uuedzc.cn);return pizza;}/*** 创建披萨(工厂方法)*/protected abstract Pizza createPizza(String type);
}
(4)创建不同风味的披萨店
/*** 纽约风味披萨店*/
public class NYStylePizzaStore extends protected Pizza createPizza(String type) {Pizza pizza = null;if ("cheese".equals(type)) {pizza = new NYStyleCheesePizza(); } else if ("clam".equals(type)) {pizza = new NYStyleClamPizza();}return pizza;}
}
/*** 芝加哥风味披萨店*/
public class ChicagoStylePizzaStore extends PizzaStore {@Overrideprotected Pizza createPizza(String type) {Pizza pizza lexuancaizc.cn= null;if (www.chuancenpt.com"cheese".equals(type)) {pizza = new ChicagoStyleCheesePizza(www.yuntianyul.com ); } else if ( www.jintianxuesha.com"clam".equals(type)) {pizza = new ChicagoStyleClamPizza();}return pizza;}
}
(5)使用不同风味的披萨店订购披萨
public class Test {public static void main(String[] args) {// 纽约风味披萨店PizzaStore nyStore = new NYStylePizzaStore();// 芝加哥风味披萨店PizzaStore chicagoStore = new ChicagoStylePizzaStore();// 订购芝士披萨Pizza pizza = nyStore.orderPizza("cheese");System.out.println("Ethan ordered a " + pizza.getName() + "\n");pizza = chicagoStore.orderPizza("cheese");System.out.println("Joel ordered a " + pizza.getName() + "\n");
创建具体的产品,并继承产品抽象类相关推荐
- 【Groovy】自定义 Xml 生成器 BuilderSupport ( 继承 BuilderSupport 抽象类 | 在 createNode 方法中获取节点名称、节点属性、节点值信息 )
文章目录 一.继承 BuilderSupport 抽象类 二.在 createNode 方法中获取节点名称.节点属性.节点值信息 三.完整代码示例 1.MyBuilderSupport 生成器代码 2 ...
- 10.java基础----继承、抽象类- 编程
命名要求:1. 类名,接口名,枚举名,注解名使用大驼峰2. 变量名,方法名,包名均使用小驼峰3. 常量名全大写,多个单词下划线分割4. 名字要见名知意,如果不知道对应的英文,可以使用拼音代替.不可使用 ...
- 【设计模式】抽象工厂模式 ( 简介 | 适用场景 | 优缺点 | 产品等级结构和产品族 | 代码示例 )
文章目录 一.抽象工厂模式简介 二.抽象工厂模式适用场景 三.抽象工厂模式优缺点 四.产品等级结构和产品族 五.抽象工厂模式代码示例 1.冰箱抽象类 2.美的冰箱实现类 3.格力冰箱实现类 4.空调抽 ...
- 《Java技术》第三次作业--面向对象——继承、抽象类、接口
1.阅读下面程序,分析是否能编译通过?如果不能,说明原因.应该如何修改?程序的运行结果是什么?为什么子类的构造方法在运行之前,必须调用父 类的构造方法?能不能反过来? class Grandparen ...
- 设计模式---4(抽象工厂模式的概念,产品组和产品等级的概念,抽象工厂模式的实现)
抽象工厂模式 抽象工厂模式的概念 抽象工厂模式是所有形态的工厂模式中最为抽象和最其一般性的.抽象工厂模式可以向 客户端提供一个接口,使得客户端在不必指定产品的具体类型的情况下,能够创建多个产品 族的产 ...
- 产品经理如何通过拆产品,持续提升产品能力?附案例
产品经理要持续提升产品能力,必须进行高密度的思考.决策和实践,不断重复这个循环. 但有时需求并不多,项目也不是特别急,没有太多实践的机会,这时,最好的提升方式就是练习,通过拆解直接竞品或其他产品,去学 ...
- 接口类的多继承以及抽象类的单继承
接口类的多继承以及抽象类的单继承 一.接口类(面向对象开发的思想和规范)的多继承 需求: 定义一个tiger类:会走,会游 定义一个hawk类:会走,会飞 定义一个swan类:会走,会游,会飞 (a) ...
- Java面向对象(继承、抽象类)
面向对象 今日内容介绍 u 继承 u 抽象类 第1章 继承 1.1 继承的概念 在现实生活中,继承一般指的是子女继承父辈的财产.在程序中,继承描述的是事物之间的所属关系,通过继承可以使多种事物之间形成 ...
- 深入继承之抽象类和接口综合分析及完整案列解说(一)
首先感谢园里的一位前辈anytao.cnblogs.com ,他对面向抽象类和接口编程作出比较完善的总结.下面的总结是直接Copy他的原话. 一.相同点 ● 都不能被直接实例化,都可以通过继承实现其抽 ...
最新文章
- Linxu终端gcc与gcc -c的区别
- 【PHPWord】插入Excel对象
- mysql子查询为什么不走索引_解决MySQL中IN子查询会导致无法使用索引问题
- linux怎么命令设置网络连接,Linux网络操作命令
- python 导入包 作用域_Python 包、模块、函数、变量作用域
- 汉诺塔问题(信息学奥赛一本通-T1205)
- 算法萌新如何学好动态规划(一)
- Spring-IOC 扩展点 BeanFactoryPostProcessor及其子接口解析
- 软件设计师历年真题与解析分享(05——17年)
- 系统集成项目管理工程师题型分析及章节占分比
- 无法访问工作组计算机修复工具,局域网共享一键修复工具
- 关于无线网络的静态ip与动态ip设置
- 什么是T1 mapping?
- 年轻时欠下风流情债的十大男女明星(组图)
- CAD三维图形转化成二维图形的过程具体的步骤
- RNNoise超详细解析
- 帆软数据可视化:BI区域地图制作
- Shell基础之自定义变量
- Android屏幕共享及远程控制【免root】
- 软件测试投递简历找工作总是已读不回怎么办?
热门文章
- 安卓手机哪个服务器信号最强,安卓手机最强性能前十排行,第一名再逆袭第二名有争议...
- 适合写python的电脑_文言文的适是什么意思
- 3d游戏建模行业真的能一直走下去麽?兴趣爱好能否带来面包
- 什么是软件测试(功能、接口、性能、自动化)详解
- React Native 炫酷的动画库 实现任何AE动画 lottie-react-native
- springboot+jsp志愿者岗位报名培训系统javaweb
- 虚荣指标 探索性指标 4种_为什么您应该避免使用虚荣指标并衡量重要问题
- spring关于Aspect、Joinpoint、Advice Pointcut的区别
- Python之线程的同步互斥与死锁
- web服务器的相关配置