工厂模式专门负责及那个大量有共同接口的类实例化,工厂模式可以动态决定奖哪一个类实例化,不必事先知道每次要实例化哪一个类。工厂模式有一下几种形态:
比如说有一个农场公司,专门向市场销售以下水果:葡萄(Grape)、草莓(Strawberry)、苹果(Apple)。
水果接口规定出所有的水果必须实现的接口:种植plant()、生长grow()、收获harvest().
其UML类图如下:

那么水果接口的代码如下:
package com.charon.factory.simpleFactory;
/**
* @className: Fruit
* @description: 水果接口
* @author: charon
* @create: 2022-03-06 20:30
*/
public interface Fruit {
/**
* 种植
*/
void plant();
/**
* 生长
*/
void grow();
/**
* 收获
*/
void harvest();
}
草莓类是水果类的一种,因此他实现了水果接口中所有声明的方法。
package com.charon.factory.simpleFactory;
/**
* @className: Strawberry
* @description:
* @author: charon
* @create: 2022-03-06 20:43
*/
public class Strawberry implements Fruit{
@Override
public void plant() {
System.out.println("草莓种植了。。。。");
}
@Override
public void grow() {
System.out.println("草莓生长中。。。。");
}
@Override
public void harvest() {
System.out.println("草莓收获了。。。。");
}
}
苹果类也是水果类的一种,因此他实现了水果接口中所有声明的方法:
package com.charon.factory.simpleFactory;
/**
* @className: Apple
* @description:
* @author: charon
* @create: 2022-03-06 20:36
*/
public class Apple implements Fruit{
@Override
public void plant() {
System.out.println("苹果树种植了。。。。");
}
@Override
public void grow() {
System.out.println("苹果树生长中。。。。");
}
@Override
public void harvest() {
System.out.println("苹果树收获了。。。。");
}
}
葡萄类也是水果类的一种,因此他实现了水果接口中所有声明的方法:
package com.charon.factory.simpleFactory;
/**
* @className: Grape
* @description:
* @author: charon
* @create: 2022-03-06 20:41
*/
public class Grape implements Fruit{
@Override
public void plant() {
System.out.println("葡萄种植了。。。。");
}
@Override
public void grow() {
System.out.println("葡萄生长中。。。。");
}
@Override
public void harvest() {
System.out.println("葡萄收获了。。。。");
}
}
FruitGardener类是园丁类,会根据客户端的要求,创建出不同的水果对象,所有的创建对象的任务都由这个类完成。
package com.charon.factory.simpleFactory;
/**
* @className: FruitGardener
* @description: 园丁类
* @author: charon
* @create: 2022-03-06 20:46
*/
public class FruitGardener {
/**
* 静态工厂方法
*
* @param fruitType 水果类型
* @return
*/
public static Fruit factory(String fruitType) {
if ("apple".equalsIgnoreCase(fruitType)) {
return new Apple();
} else if ("Grape".equalsIgnoreCase(fruitType)) {
return new Grape();
} else if ("Strawberry".equalsIgnoreCase(fruitType)) {
return new Strawberry();
}
return null;
}
}
测试:
package com.charon.factory.simpleFactory;
/**
* @className: Test
* @description:
* @author: charon
* @create: 2022-03-06 20:50
*/
public class Test {
public static void main(String[] args) {
Fruit apple = FruitGardener.factory("apple");
apple.plant();
apple.grow();
apple.harvest();
Fruit grape = FruitGardener.factory("grape");
grape.plant();
grape.grow();
grape.harvest();
Fruit strawberry = FruitGardener.factory("strawberry");
strawberry.plant();
strawberry.grow();
strawberry.harvest();
}
}
打印结果:
苹果树种植了。。。。
苹果树生长中。。。。
苹果树收获了。。。。
葡萄种植了。。。。
葡萄生长中。。。。
葡萄收获了。。。。
草莓种植了。。。。
草莓生长中。。。。
草莓收获了。。。。
简单工厂模式就是由一个工厂类根据传入的参数决定创建出哪一种产品的类的实例。
这种模式的优点:好理解,简单易操作。
这种模式的缺点:违反了设计模式的ocp原则,即对扩展开放,对修改关闭。
如果我们需要新添加一种水果,那么需要新添加一个水果类,还需要在FruitGardener中添加这种水果的实例化。同时,由于使用的静态方法作为的工厂方法,而静态方法无法由子类继承,因此,工厂角色无法形成基于继承的等级结构。
从上面可以知道,简单工厂模式涉及到工厂角色、抽象产品角色以及具体产品角色:
工厂方法模式是简单工厂模式的进一步抽象和推广。由于使用了多态性,工厂方法模式保持了简单工厂模式的优点,也克服了他的缺点。在工厂方法模式中,核心的工厂类不再负责所有的产品的创建,而是将具体创建的工作交给子类去做,这个核心类则成为了一个抽象工厂角色,仅负责给出具体工厂子类必须实现的接口,而不是接触哪一个产品类应当被实例化这种细节。
还是上面的例子。由于农场规模扩大,一个园丁已经处理不过来了,所以现在每一种水果都需要专门的园丁来管理了。那么上面的FruitGardener这个全能角色就成了抽象的园丁角色,这个角色规定出具体园丁角色需要实现的具体职能,而真正负责水果管理的则是具体的园丁角色。
本系统的UML类图如下:

FruitGardener接口类:
package com.charon.factory.factoryMethod;
import com.charon.factory.simpleFactory.Fruit;
/**
* @className: FruitGardener
* @description: 园丁类
* @author: charon
* @create: 2022-03-06 20:46
*/
public interface FruitGardener {
/**
* 静态工厂方法
*
* @param fruitType 水果类型
* @return
*/
Fruit factory();
}
AppleGardener类是具体工厂类,它实现了FruitGardener 接口,提供了工厂方法的实现:
package com.charon.factory.factoryMethod;
import com.charon.factory.simpleFactory.Apple;
import com.charon.factory.simpleFactory.Fruit;
/**
* @className: AppleGardener
* @description:
* @author: charon
* @create: 2022-03-06 23:04
*/
public class AppleGardener implements FruitGardener{
@Override
public Fruit factory() {
return new Apple();
}
}
GrapeGardener类是具体工厂类,它实现了FruitGardener 接口,提供了工厂方法的实现:
package com.charon.factory.factoryMethod;
import com.charon.factory.simpleFactory.Fruit;
import com.charon.factory.simpleFactory.Grape;
/**
* @className: GrapeGardener
* @description:
* @author: charon
* @create: 2022-03-06 23:04
*/
public class GrapeGardener implements FruitGardener{
@Override
public Fruit factory() {
return new Grape();
}
}
StrawberryGardener类是具体工厂类,它实现了FruitGardener 接口,提供了工厂方法的实现:
package com.charon.factory.factoryMethod;
import com.charon.factory.simpleFactory.Fruit;
import com.charon.factory.simpleFactory.Strawberry;
/**
* @className: StrawberryGardener
* @description:
* @author: charon
* @create: 2022-03-06 23:04
*/
public class StrawberryGardener implements FruitGardener{
@Override
public Fruit factory() {
return new Strawberry();
}
}
Test类:
package com.charon.factory.factoryMethod;
import com.charon.factory.simpleFactory.Fruit;
/**
* @className: Test
* @description:
* @author: charon
* @create: 2022-03-06 23:11
*/
public class Test {
public static void main(String[] args) {
FruitGardener appleGardener = new AppleGardener();
Fruit apple = appleGardener.factory();
apple.plant();
apple.plant();
apple.harvest();
FruitGardener grapeGardener = new GrapeGardener();
Fruit grape = grapeGardener.factory();
grape.plant();
grape.plant();
grape.harvest();
FruitGardener strawberryGardener = new StrawberryGardener();
Fruit strawberry = strawberryGardener.factory();
strawberry.plant();
strawberry.plant();
strawberry.harvest();
}
}
打印结果:
苹果树种植了。。。。
苹果树生长中。。。。
苹果树收获了。。。。
葡萄种植了。。。。
葡萄生长中。。。。
葡萄收获了。。。。
草莓种植了。。。。
草莓生长中。。。。
草莓收获了。。。。
从上面可以知道,工厂方法模式涉及到抽象工厂角色、具体工厂角色、抽象产品角色以及具体产品角色:
抽象工厂模式可以向客户端提供一个接口,使得客户端在不必指定产品的具体类型的情况下,创建多个产品族中的产品对象。这就是抽象工厂模式的用意。
为了方便引进抽象工厂模式,特地引进了一个新的概念:产品族,是指与不同产品等级结构中功能相关联的产品组成的家族。
还是上面的例子。随着市场的扩大,农场公司再次面临新的发展,引入了蔬菜大棚技术,在大棚内种植热带和亚热带的水果和蔬菜。
因此在这个系统里,产品分成两个等级结构:水果(热带水果,亚热带水果)和蔬菜(热带蔬菜,亚热带蔬菜)。园丁呢,也分成两类:管理热带水果蔬菜的园丁(tropicGardener)和管理亚热带水果蔬菜的园丁(subtropicalGardener)。
本系统的UML类图如下:

Fruit 水果接口类:
package com.charon.factory.absFactory;
/**
* @className: Fruit
* @description: 水果类
* @author: charon
* @create: 2022-03-08 22:12
*/
public interface Fruit {
}
TropicFruit 热带水果实现类:
package com.charon.factory.absFactory;
/**
* @className: TropicFruit
* @description: 热带水果
* @author: charon
* @create: 2022-03-08 22:13
*/
public class TropicFruit implements Fruit{
private String name;
public TropicFruit(String name) {
this.name = name;
System.out.println("热带水果: "+ name);
}
}
SubtropicFruit 亚热带水果实现类:
package com.charon.factory.absFactory;
/**
* @className: TropicFruit
* @description: 亚热带水果
* @author: charon
* @create: 2022-03-08 22:13
*/
public class SubtropicFruit implements Fruit{
private String name;
public SubtropicFruit(String name) {
this.name = name;
System.out.println("亚热带水果: "+ name);
}
}
Veggie 蔬菜类接口:
package com.charon.factory.absFactory;
/**
* @className: Veggie
* @description: 蔬菜类
* @author: charon
* @create: 2022-03-08 22:12
*/
public interface Veggie {
}
TropicVeggie 热带蔬菜:
package com.charon.factory.absFactory;
/**
* @className: TropicVeggie
* @description: 热带蔬菜
* @author: charon
* @create: 2022-03-08 22:13
*/
public class TropicVeggie implements Veggie{
private String name;
public TropicVeggie(String name) {
this.name = name;
System.out.println("热带蔬菜: "+ name);
}
}
SubtropicVeggie 亚热带蔬菜:
package com.charon.factory.absFactory;
/**
* @className: TropicVeggie
* @description: 热带蔬菜
* @author: charon
* @create: 2022-03-08 22:13
*/
public class SubtropicVeggie implements Veggie{
private String name;
public SubtropicVeggie(String name) {
this.name = name;
System.out.println("亚热带蔬菜: "+ name);
}
}
Gardener 园丁接口类:
package com.charon.factory.absFactory;
/**
* @className: Gardener
* @description: 园丁的顶级接口
* @author: charon
* @create: 2022-03-08 22:09
*/
public interface Gardener {
/**
* 创建亚热带水果
* @return
*/
Fruit createFruit();
/**
* 创建亚热带蔬菜
* @return
*/
Veggie createVeggie();
}
TropicGardener 热带园丁类:
package com.charon.factory.absFactory;
/**
* @className: TropicGardener
* @description: 管理热带水果蔬菜的园丁类
* @author: charon
* @create: 2022-03-08 22:10
*/
public class TropicGardener implements Gardener{
/**
* 创建热带水果
* @return
*/
@Override
public Fruit createFruit(){
return new TropicFruit("苹果");
}
/**
* 创建热带蔬菜
* @return
*/
@Override
public Veggie createVeggie(){
return new TropicVeggie("白菜");
}
}
SubtropicGardener 亚热带园丁类:
package com.charon.factory.absFactory;
import java.util.concurrent.Future;
/**
* @className: SubtropicGardener
* @description: 管理亚热带水果蔬菜的园丁类
* @author: charon
* @create: 2022-03-08 22:11
*/
public class SubtropicGardener implements Gardener{
/**
* 创建亚热带水果
* @return
*/
@Override
public Fruit createFruit(){
return new SubtropicFruit("苹果");
}
/**
* 创建亚热带蔬菜
* @return
*/
@Override
public Veggie createVeggie(){
return new SubtropicVeggie("白菜");
}
}
test 测试类:
package com.charon.factory.absFactory;
/**
* @className: Test
* @description:
* @author: charon
* @create: 2022-03-08 22:23
*/
public class Test {
public static void main(String[] args) {
Gardener tropicGardener = new TropicGardener();
tropicGardener.createFruit();
tropicGardener.createVeggie();
Gardener subtropicGardener = new SubtropicGardener();
subtropicGardener.createFruit();
subtropicGardener.createVeggie();
}
}
抽象工厂模式涉及到一下的角色:
我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co
在railstutorial中,作者为什么选择使用这个(代码list10.25):http://ruby.railstutorial.org/chapters/updating-showing-and-deleting-usersnamespace:dbdodesc"Filldatabasewithsampledata"task:populate=>:environmentdoRake::Task['db:reset'].invokeUser.create!(:name=>"ExampleUser",:email=>"example@railstutorial.org",:passwo
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende
我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数
给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最
目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称
项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU
了解Rails缓存如何工作的人可以真正帮助我。这是嵌套在Rails::Initializer.runblock中的代码:config.after_initializedoSomeClass.const_set'SOME_CONST','SOME_VAL'end现在,如果我运行script/server并发出请求,一切都很好。然而,在我的Rails应用程序的第二个请求中,一切都因单元化常量错误而变得糟糕。在生产模式下,我可以成功发出第二个请求,这意味着常量仍然存在。我已通过将以上内容更改为以下内容来解决问题:config.after_initializedorequire'some_cl
我在我的项目中有一个用户和一个管理员角色。我使用Devise创建了身份验证。在我的管理员角色中,我没有任何确认。在我的用户模型中,我有以下内容:devise:database_authenticatable,:confirmable,:recoverable,:rememberable,:trackable,:validatable,:timeoutable,:registerable#Setupaccessible(orprotected)attributesforyourmodelattr_accessible:email,:username,:prename,:surname,: