最近看工厂方法模式时有点疑问,请各位帮忙解决一下~
如下:
我在教程上看到说,如果想在系统中新加一个新的产品,则只需要向系统中加入一个新的产品类,以及他所对就原工厂类即可.而不用修改客户端代码.
我觉得客户端代码还是要需改的,请问这是为什么啊?哪儿理解有问题啊~!
在线等~1
如下:
我在教程上看到说,如果想在系统中新加一个新的产品,则只需要向系统中加入一个新的产品类,以及他所对就原工厂类即可.而不用修改客户端代码.
我觉得客户端代码还是要需改的,请问这是为什么啊?哪儿理解有问题啊~!
在线等~1
解决方案 »
- 求Boolean类中toString方法的使用简单例子
- String类的charAt能返回指定索引字符,用什么来设置指定索引字符?
- 请问 2个大小不同的图片,怎么实现按位置叠加(小的图片按位置覆盖大的图片的某区域),形成一个图片?
- toString()方法的一个问题
- 如何使用Java提取某个类的serialVersionUID
- 高人指点!
- 请各位大哥帮我这个小弟一下啥.谢谢大家!!!!
- 关于equals的问题(菜鸟问题)
- 我装完j2se后设置为:path:D:\liuwenxi\j2se\bin,classpath:D:\liuwenxi\j2se\lib\tools.jar;D:\liuwenxi\j2se\lib\dt.jar
- 在使用了ResultSet.first()之后,能够获得数据吗?
- java与ZPL通信
- html如何设置input的无边框效果
楼主【feiyuxianwan】截止到2008-07-25 11:20:13的历史汇总数据(不包括此帖):
发帖的总数量:27 发帖的总分数:420 每贴平均分数:15
回帖的总数量:15 得分贴总数量:3 回帖的得分率:20%
结贴的总数量:6 结贴的总分数:100
无满意结贴数:0 无满意结贴分:0
未结的帖子数:21 未结的总分数:320
结贴的百分比:22.22 % 结分的百分比:23.81 %
无满意结贴率:0.00 % 无满意结分率:0.00 %
楼主该结一些帖子了
我觉得我们平时经常使用的数据库例子就是很好的工厂模式的例子, 各种数据库jdbc中的class都实现了java.util.sql 下的接口,
我们"客户端"调用的语句
ResultSet rs = stmt.executeQuery("select * from table1");
就是说如何有一天,你自己增加一种数据库,只要实现java.util.sql 下的 接口,
客户端同样用:ResultSet rs = stmt.executeQuery("select * from table1"); 就可以得到结果. 这应该就是说你所说的客户端不用修改代码的情况了.
/**
* Created by IntelliJ IDEA.
* FileName:Fruit.java
* User: LavaSoft
* Date: 2006-12-3
* Time: 17:25:48
* 《Java与模式》(--阎宏博士著)读书笔记
* 工厂模式--工厂方法模式--一般性模式(农场应用)
* ReadMe: 水果接口
*/
public interface Fruit {
/**
* 种植
*/
void plant();
/**
* 生长
*/
void grow();
/**
* 收获
*/
void harvest();
}
1.2.3.3.2 具体产品苹果Apple.java
package com.lavasoft.patterns.factorymethod.ybms;
/**
* Created by IntelliJ IDEA.
* FileName:Apple.java
* User: LavaSoft
* Date: 2006-12-1
* Time: 0:47:25
* 《Java与模式》(--阎宏博士著)读书笔记
* 工厂模式--工厂方法模式--一般性模式(农场应用)
* ReadMe: 水果工厂的产品:苹果
*/
public class Apple implements Fruit {
private int treeAge;
/**
* 种植
*/
public void plant() {
System.out.println("Apple has been planted.");
}
/**
* 生长
*/
public void grow() {
System.out.println("Apple is growing...");
}
/**
* 收获
*/
public void harvest() {
System.out.println("Apple has been harvested.");
}
/**
* @return 返回树龄
*/
public int getTreeAge() {
return treeAge;
}
/**
* 设置树龄
*/
public void setTreeAge(int treeAge) {
this.treeAge = treeAge;
}
}1.2.3.3.3 具体产品葡萄:Grape.java
package com.lavasoft.patterns.factorymethod.ybms;
/**
* Created by IntelliJ IDEA.
* FileName:Grape.java
* User: LavaSoft
* Date: 2006-12-1
* Time: 0:36:56
* 《Java与模式》(--阎宏博士著)读书笔记
* 工厂模式--工厂方法模式--一般性模式(农场应用)
* ReadMe: 水果工厂的产品:葡萄
*/
public class Grape implements Fruit {
private boolean seedless; //是否有籽
/**
* 种植
*/
public void plant() {
System.out.println("Grape has been planted.");
}
/**
* 生长
*/
public void grow() {
System.out.println("Grape is growing...");
}
/**
* 收获
*/
public void harvest() {
System.out.println("Grape has been harvested.");
}
/**
* @return 是否有籽
*/
public boolean getSeedless() {
return seedless;
}
/**
* 有无籽的赋值方法
*/
public void setSeedless(boolean seedless) {
this.seedless = seedless;
}
/**
* 辅助方法
*/
public static void log(String msg) {
System.out.println(msg);
}
}1.2.3.3.4 具体产品草莓:Strawberry.java
package com.lavasoft.patterns.factorymethod.ybms;/**
* Created by IntelliJ IDEA.
* FileName:Strawberry.java
* User: LavaSoft
* Date: 2006-12-1
* Time: 0:45:09
* 《Java与模式》(--阎宏博士著)读书笔记
* 工厂模式--工厂方法模式--一般性模式(农场应用)
* ReadMe: 水果工厂的产品:草莓
*/
public class Strawberry implements Fruit {
/**
* 生长
*/
public void grow() {
System.out.println("Strawberry is growing...");
}
/**
* 收获
*/
public void harvest() {
System.out.println("Strawberry has been harvested.");
}
/**
* 种植
*/
public void plant() {
System.out.println("Strawberry has been planted.");
}
/**
* 辅助方法
*/
public static void log(String msg) {
System.out.println(msg);
}
}
1.2.3.3.5 水果工厂接口:FruitGardener.java
package com.lavasoft.patterns.factorymethod.ybms;
/**
* Created by IntelliJ IDEA.
* FileName:FruitGardener.java
* User: LavaSoft
* Date: 2006-12-3
* Time: 17:22:52
* 《Java与模式》(--阎宏博士著)读书笔记
* 工厂模式--工厂方法模式--一般性模式(农场应用)
* ReadMe: 水果工厂接口
*/
public interface FruitGardener {
/**
* 工厂方法
*
* @return 水果
*/
public Fruit factory();
}
1.2.3.3.6 苹果工厂:AppleGardener.java
package com.lavasoft.patterns.factorymethod.ybms;
/**
* Created by IntelliJ IDEA.
* FileName:AppleGardener.java
* User: LavaSoft
* Date: 2006-12-3
* Time: 17:45:29
* 《Java与模式》(--阎宏博士著)读书笔记
* 工厂模式--工厂方法模式--一般性模式(农场应用)
* ReadMe: 苹果工厂方法
*/
public class AppleGardener implements FruitGardener {
/**
* 工厂方法
*
* @return 苹果
*/
public Fruit factory() {
Fruit f = new Apple();
System.out.println("水果工厂(AppletGardener)成功创建一个水果:苹果!");
return f;
}
}
1.2.3.3.7 葡萄工厂:GrapeGardener.java
package com.lavasoft.patterns.factorymethod.ybms;
/**
* Created by IntelliJ IDEA.
* FileName:GrapeGardener.java
* User: LavaSoft
* Date: 2006-12-3
* Time: 17:51:41
* 《Java与模式》(--阎宏博士著)读书笔记
* 工厂模式--工厂方法模式--一般性模式(农场应用)
* ReadMe: 添加说明
*/
public class GrapeGardener implements FruitGardener {
/**
* 工厂方法
*
* @return 葡萄
*/
public Fruit factory() {
Fruit f = new Grape();
System.out.println("水果工厂(GrapeGardener)成功创建一个水果:葡萄!");
return f;
}
}
1.2.3.3.8 草莓工厂:StrawberryGardener.java
package com.lavasoft.patterns.factorymethod.ybms;
/**
* Created by IntelliJ IDEA.
* FileName:StrawberryGardener.java
* User: LavaSoft
* Date: 2006-12-3
* Time: 17:53:30
* 《Java与模式》(--阎宏博士著)读书笔记
* 工厂模式--工厂方法模式--一般性模式(农场应用)
* ReadMe: 添加说明
*/
public class StrawberryGardener implements FruitGardener {
/**
* 工厂方法
*
* @return 草莓
*/
public Fruit factory() {
Fruit f = new Strawberry();
System.out.println("水果工厂(StrawberryGardener)成功创建一个水果:草莓!");
return f;
}
}
1.2.3.3.9 测试类(客户端):TestApp.java
package com.lavasoft.patterns.factorymethod.ybms;
/**
* Created by IntelliJ IDEA.
* FileName:TestApp.java
* User: LavaSoft
* Date: 2006-12-3
* Time: 17:54:48
* 《Java与模式》(--阎宏博士著)读书笔记
* 工厂模式--工厂方法模式--一般性模式(农场应用)
* ReadMe: 测试类(客户端)
*/
public class TestApp {
private FruitGardener f1, f2, f3;
private Fruit p1, p2, p3;
private void test() {
//实力化水果工厂
f1 = new AppleGardener();
f2 = new GrapeGardener();
f3 = new StrawberryGardener();
//从水果工厂生产水果
p1 = f1.factory();
p2 = f2.factory();
p3 = f3.factory();
}
public static void main(String args[]) {
TestApp test = new TestApp();
test.test();
}
}如要说我现在加一个新的产品,名称叫:香焦,首先我得创建香焦的具体产品,即实现接口,还要创建一个香蕉工厂,那么我在客户端要生产一个香蕉不还得改客户端的代码吗?
客户端并不是我们C/S架构里面的客户端,它应该只的是模式的使用者.
楼上的几位应该解释清楚了.目的是,只添加不更改.抽象工厂模式应该可以达到这样的原则.友情up
我决的应该是客户端。我还是理解不了,在TestApp怎么可能不要动代码呢。之所以说不要修改代码,应该说的是:如果现在要在TestApp里用香蕉,那TestApp里的已有的代码不会被修改,而是直接在后面添加代码。??
config
Config.java
config.properties (默认配置)
fruit
impl
Apple.java
Orange.java
DefaultFruit.java
Fruit.java
FruitFactory.java
FruitTest.java
config.properties (使用配置)FruitTest.java 测试类
package com.fruit;public class FruitTest { public static void main(String[] args) {
Fruit fruit = FruitFactory.getFruit();
fruit.printName();
}
}Fruit.java Fruit 的接口
package com.fruit;public interface Fruit {
// 输出 Fruit 的名字
public void printName();
}Apple.java Fruit 的一个实现
package com.fruit.impl;import com.fruit.Fruit;public class Apple implements Fruit {
public void printName() {
System.out.println("Hello, I am a apple!");
}
}Orange.java Fruit 的一个实现
package com.fruit.impl;import com.fruit.Fruit;public class Orange implements Fruit { public void printName() {
System.out.println("Hello, I am a Orange!");
}
}DefaultFruit.java Fruit 的默认实现
package com.fruit.impl;import com.fruit.Fruit;public class DefaultFruit implements Fruit { public void printName() {
System.out.println("Hello, I am a default fruit!");
}
}FruitFactory.java 产生 Fruit 的工厂
package com.fruit;import com.fruit.config.Config;public class FruitFactory {
public static Fruit getFruit() {
Class clazz = null;
try {
// 加载 Class 对象
clazz = Class.forName(Config.getInstance().getFruitImpl());
} catch (ClassNotFoundException e) {
try {
// 加载 Class 失败,即配置中的类不存在,这时使用默认的实现
clazz = Class.forName(Config.getInstance().getDefaultFruitImpl());
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
return null;
}
}
Fruit fruit = null;
try {
fruit = (Fruit)clazz.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return fruit;
}
}Config.java 加载配置文件
package com.fruit.config;import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;public class Config {
private final static String CONFIG_FILE_NAME = "config.properties";
private final static String FRUIT_IMPL_KEY = "fruit.impl";
private final static String DEFAULT_FRUIT_IMPL = "com.fruit.impl.DefaultFruit";
private Properties pro = new Properties();
private static Config config = new Config();
private Config() {
init();
}
public static Config getInstance() {
return config;
}
public String getFruitImpl() {
String impl = pro.getProperty(FRUIT_IMPL_KEY);
if(impl == null || impl.trim().length() == 0) {
// 如果配置中不存在 Fruit 实现类的配置,则使用默认的实现
impl = getDefaultFruitImpl();
pro.setProperty(FRUIT_IMPL_KEY, impl);
}
return impl;
}
public String getDefaultFruitImpl() {
return DEFAULT_FRUIT_IMPL;
}
private void init() {
try {
// 从根路径中加载配置文件
pro.load(new FileInputStream(CONFIG_FILE_NAME));
} catch (IOException e) {
try {
// 根路径中若没有找到,则加载 com.fruit.config 中同名配置文件
pro.load(Config.class.getResourceAsStream(CONFIG_FILE_NAME));
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}com.fruit.config 目录中的 config.properties 配置文件
fruit.impl=com.fruit.impl.DefaultFruit应用根路径中的 config.properties 配置文件
fruit.impl=com.fruit.impl.Apple通过以上的代码,如果以后要增加一个新的水果,只要写一个类实现 Fruit 就行了,如果要使用这个
新写的类的话,可以把应用根路径中的 config.properties 相关配置改一行就可以了。这样我们就
降低了耦合程度,原来写好的代码可以一行不动地开始使用新写的类。需要注意的是,不修改是指不对已有的代码进行改动,而不是指不能增加新的实现,这也是面向对象设
计原则中开-闭原则(OCP)所要求的,即对新增的功能开放,对已有代码
的修改关闭。
/**
* Created by IntelliJ IDEA.
* FileName:Fruit.java
* User: LavaSoft
* Date: 2006-12-3
* Time: 17:25:48
* 《Java与模式》(--阎宏博士著)读书笔记
* 工厂模式--工厂方法模式--一般性模式(农场应用)
* ReadMe: 水果接口
*/
public interface Fruit {
/**
* 种植
*/
void plant();
/**
* 生长
*/
void grow();
/**
* 收获
*/
void harvest();
}
1.2.3.3.2 具体产品苹果Apple.java
package com.lavasoft.patterns.factorymethod.ybms;
/**
* Created by IntelliJ IDEA.
* FileName:Apple.java
* User: LavaSoft
* Date: 2006-12-1
* Time: 0:47:25
* 《Java与模式》(--阎宏博士著)读书笔记
* 工厂模式--工厂方法模式--一般性模式(农场应用)
* ReadMe: 水果工厂的产品:苹果
*/
public class Apple implements Fruit {
private int treeAge;
/**
* 种植
*/
public void plant() {
System.out.println("Apple has been planted.");
}
/**
* 生长
*/
public void grow() {
System.out.println("Apple is growing...");
}
/**
* 收获
*/
public void harvest() {
System.out.println("Apple has been harvested.");
}
/**
* @return 返回树龄
*/
public int getTreeAge() {
return treeAge;
}
/**
* 设置树龄
*/
public void setTreeAge(int treeAge) {
this.treeAge = treeAge;
}
}1.2.3.3.3 具体产品葡萄:Grape.java
package com.lavasoft.patterns.factorymethod.ybms;
/**
* Created by IntelliJ IDEA.
* FileName:Grape.java
* User: LavaSoft
* Date: 2006-12-1
* Time: 0:36:56
* 《Java与模式》(--阎宏博士著)读书笔记
* 工厂模式--工厂方法模式--一般性模式(农场应用)
* ReadMe: 水果工厂的产品:葡萄
*/
public class Grape implements Fruit {
private boolean seedless; //是否有籽
/**
* 种植
*/
public void plant() {
System.out.println("Grape has been planted.");
}
/**
* 生长
*/
public void grow() {
System.out.println("Grape is growing...");
}
/**
* 收获
*/
public void harvest() {
System.out.println("Grape has been harvested.");
}
/**
* @return 是否有籽
*/
public boolean getSeedless() {
return seedless;
}
/**
* 有无籽的赋值方法
*/
public void setSeedless(boolean seedless) {
this.seedless = seedless;
}
/**
* 辅助方法
*/
public static void log(String msg) {
System.out.println(msg);
}
}1.2.3.3.4 具体产品草莓:Strawberry.java
package com.lavasoft.patterns.factorymethod.ybms;/**
* Created by IntelliJ IDEA.
* FileName:Strawberry.java
* User: LavaSoft
* Date: 2006-12-1
* Time: 0:45:09
* 《Java与模式》(--阎宏博士著)读书笔记
* 工厂模式--工厂方法模式--一般性模式(农场应用)
* ReadMe: 水果工厂的产品:草莓
*/
public class Strawberry implements Fruit {
/**
* 生长
*/
public void grow() {
System.out.println("Strawberry is growing...");
}
/**
* 收获
*/
public void harvest() {
System.out.println("Strawberry has been harvested.");
}
/**
* 种植
*/
public void plant() {
System.out.println("Strawberry has been planted.");
}
/**
* 辅助方法
*/
public static void log(String msg) {
System.out.println(msg);
}
}
1.2.3.3.5 水果工厂接口:FruitGardener.java
package com.lavasoft.patterns.factorymethod.ybms;
/**
* Created by IntelliJ IDEA.
* FileName:FruitGardener.java
* User: LavaSoft
* Date: 2006-12-3
* Time: 17:22:52
* 《Java与模式》(--阎宏博士著)读书笔记
* 工厂模式--工厂方法模式--一般性模式(农场应用)
* ReadMe: 水果工厂接口
*/
public interface FruitGardener {
/**
* 工厂方法
*
* @return 水果
*/
public Fruit factory();
}
1.2.3.3.6 苹果工厂:AppleGardener.java
package com.lavasoft.patterns.factorymethod.ybms;
/**
* Created by IntelliJ IDEA.
* FileName:AppleGardener.java
* User: LavaSoft
* Date: 2006-12-3
* Time: 17:45:29
* 《Java与模式》(--阎宏博士著)读书笔记
* 工厂模式--工厂方法模式--一般性模式(农场应用)
* ReadMe: 苹果工厂方法
*/
public class AppleGardener implements FruitGardener {
/**
* 工厂方法
*
* @return 苹果
*/
public Fruit factory() {
Fruit f = new Apple();
System.out.println("水果工厂(AppletGardener)成功创建一个水果:苹果!");
return f;
}
}
1.2.3.3.7 葡萄工厂:GrapeGardener.java
package com.lavasoft.patterns.factorymethod.ybms;
/**
* Created by IntelliJ IDEA.
* FileName:GrapeGardener.java
* User: LavaSoft
* Date: 2006-12-3
* Time: 17:51:41
* 《Java与模式》(--阎宏博士著)读书笔记
* 工厂模式--工厂方法模式--一般性模式(农场应用)
* ReadMe: 添加说明
*/
public class GrapeGardener implements FruitGardener {
/**
* 工厂方法
*
* @return 葡萄
*/
public Fruit factory() {
Fruit f = new Grape();
System.out.println("水果工厂(GrapeGardener)成功创建一个水果:葡萄!");
return f;
}
}
1.2.3.3.8 草莓工厂:StrawberryGardener.java
package com.lavasoft.patterns.factorymethod.ybms;
/**
* Created by IntelliJ IDEA.
* FileName:StrawberryGardener.java
* User: LavaSoft
* Date: 2006-12-3
* Time: 17:53:30
* 《Java与模式》(--阎宏博士著)读书笔记
* 工厂模式--工厂方法模式--一般性模式(农场应用)
* ReadMe: 添加说明
*/
public class StrawberryGardener implements FruitGardener {
/**
* 工厂方法
*
* @return 草莓
*/
public Fruit factory() {
Fruit f = new Strawberry();
System.out.println("水果工厂(StrawberryGardener)成功创建一个水果:草莓!");
return f;
}
}
1.2.3.3.9 测试类(客户端):TestApp.java
package com.lavasoft.patterns.factorymethod.ybms;
/**
* Created by IntelliJ IDEA.
* FileName:TestApp.java
* User: LavaSoft
* Date: 2006-12-3
* Time: 17:54:48
* 《Java与模式》(--阎宏博士著)读书笔记
* 工厂模式--工厂方法模式--一般性模式(农场应用)
* ReadMe: 测试类(客户端)
*/
public class TestApp {
private FruitGardener f1, f2, f3;
private Fruit p1, p2, p3;
private void test() {
//实力化水果工厂
f1 = new AppleGardener();
f2 = new GrapeGardener();
f3 = new StrawberryGardener();
//从水果工厂生产水果
p1 = f1.factory();
p2 = f2.factory();
p3 = f3.factory();
}
public static void main(String args[]) {
TestApp test = new TestApp();
test.test();
}
}
楼主别看代码
请敲代码