ThinkInJava中的接口与工厂
来源:互联网 发布:录制屏幕的软件 编辑:程序博客网 时间:2024/06/05 13:30
接口是实现多重继承的途径,而生成遵循某个接口的对象的典型方式就是工厂方法设计模式.
这与直接调用构造器不同,我们在工厂对象上调用的是创建方法,而该工厂对象将生成接口的某个实现的对象.
理论上,通过这方式,我们的代码将完全与接口的实现分离,这就使得我们可以透明的将某个实现替换为另一个实现.
下面的代码实例展示了工厂方法的结构:
//: interfaces/Factories.javaimport static net.mindview.util.Print.*;interface Service { void method1(); void method2();}interface ServiceFactory { Service getService();}class Implementation1 implements Service { Implementation1() {} // Package access public void method1() {print("Implementation1 method1");} public void method2() {print("Implementation1 method2");}}class Implementation1Factory implements ServiceFactory { public Service getService() { return new Implementation1(); }}class Implementation2 implements Service { Implementation2() {} // Package access public void method1() {print("Implementation2 method1");} public void method2() {print("Implementation2 method2");}}class Implementation2Factory implements ServiceFactory { public Service getService() { return new Implementation2(); }}public class Factories { public static void serviceConsumer(ServiceFactory fact) { Service s = fact.getService(); s.method1(); s.method2(); } public static void main(String[] args) { serviceConsumer(new Implementation1Factory()); // Implementations are completely interchangeable: serviceConsumer(new Implementation2Factory()); }} /* Output:Implementation1 method1Implementation1 method2Implementation2 method1Implementation2 method2*///:~
package net.mindview.util;import java.io.*;public class Print { // Print with a newline: public static void print(Object obj) { System.out.println(obj); } // Print a newline by itself: public static void print() { System.out.println(); } // Print with no line break: public static void printnb(Object obj) { System.out.print(obj); } // The new Java SE5 printf() (from C): public static PrintStream printf(String format, Object... args) { return System.out.printf(format, args); }} ///:~
如果不是工厂方法,你的代码就必须在某处指定将要创建的Service的确切类型,以便调用合适的构造器.
为什么我们想要添加这种额外级别的间接性呢? 一个常见的原因是想要创建框架:
假设你正在创建一个对弈游戏系统, 例如,在相同的棋盘上下国际象棋和跳棋:
//: interfaces/Games.java// A Game framework using Factory Methods.import static net.mindview.util.Print.*;interface Game { boolean move(); }interface GameFactory { Game getGame(); }class Checkers implements Game { private int moves = 0; private static final int MOVES = 3; public boolean move() { print("Checkers move " + moves); return ++moves != MOVES; }}class CheckersFactory implements GameFactory { public Game getGame() { return new Checkers(); }}class Chess implements Game { private int moves = 0; private static final int MOVES = 4; public boolean move() { print("Chess move " + moves); return ++moves != MOVES; }}class ChessFactory implements GameFactory { public Game getGame() { return new Chess(); }}public class Games { public static void playGame(GameFactory factory) { Game s = factory.getGame(); while(s.move()) ; } public static void main(String[] args) { playGame(new CheckersFactory()); playGame(new ChessFactory()); }} /* Output:Checkers move 0Checkers move 1Checkers move 2Chess move 0Chess move 1Chess move 2Chess move 3*///:~如果Game类表示一段复杂的代码,那么这种方式就允许你在不同类型的游戏中复用这段代码,你可以再想象一些能够从这个模式中受益的更加精巧的游戏.
更优雅的工厂实现方式,是使用匿名内部类;
//: innerclasses/Factories.javaimport static net.mindview.util.Print.*;interface Service { void method1(); void method2();}interface ServiceFactory { Service getService();}class Implementation1 implements Service { private Implementation1() {} public void method1() {print("Implementation1 method1");} public void method2() {print("Implementation1 method2");} public static ServiceFactory factory = new ServiceFactory() { public Service getService() { return new Implementation1(); } };}class Implementation2 implements Service { private Implementation2() {} public void method1() {print("Implementation2 method1");} public void method2() {print("Implementation2 method2");} public static ServiceFactory factory = new ServiceFactory() { public Service getService() { return new Implementation2(); } };}public class Factories { public static void serviceConsumer(ServiceFactory fact) { Service s = fact.getService(); s.method1(); s.method2(); } public static void main(String[] args) { serviceConsumer(Implementation1.factory); // Implementations are completely interchangeable: serviceConsumer(Implementation2.factory); }} /* Output:Implementation1 method1Implementation1 method2Implementation2 method1Implementation2 method2*///:~现在用于Implementation1 和Implementation2的构造器都可以是私有的,并且没有任何必要去创建作为工厂的具名类.
另外,你经常只需要单一的工厂对象,因此在本实例中它被创建为Service实现中的一个static域,这样产生语法也更具实际意义
Games用匿名内部类改造:
//: innerclasses/Games.java// Using anonymous inner classes with the Game framework.import static net.mindview.util.Print.*;interface Game { boolean move(); }interface GameFactory { Game getGame(); }class Checkers implements Game { private Checkers() {} private int moves = 0; private static final int MOVES = 3; public boolean move() { print("Checkers move " + moves); return ++moves != MOVES; } public static GameFactory factory = new GameFactory() { public Game getGame() { return new Checkers(); } };}class Chess implements Game { private Chess() {} private int moves = 0; private static final int MOVES = 4; public boolean move() { print("Chess move " + moves); return ++moves != MOVES; } public static GameFactory factory = new GameFactory() { public Game getGame() { return new Chess(); } };}public class Games { public static void playGame(GameFactory factory) { Game s = factory.getGame(); while(s.move()) ; } public static void main(String[] args) { playGame(Checkers.factory); playGame(Chess.factory); }} /* Output:Checkers move 0Checkers move 1Checkers move 2Chess move 0Chess move 1Chess move 2Chess move 3*///:~
4 0
- ThinkInJava中的接口与工厂
- java中的接口与工厂
- C# 接口与工厂
- 接口与工厂
- 三层中的工厂接口架构分析
- ThinkInJava笔记
- 接口与工厂(设计模式)
- java中接口与实现接口,包含抽象工厂(代码)
- 工厂模式与抽象工厂在实际项目中的应用
- XML中的SAX接口与DOM接口
- 设计模式-工厂方法设计模式与接口的应用
- 从头认识java-7.8 接口与工厂模式
- 抽象类与接口及简单的工厂模式
- Java之接口与工厂详解一(附源码)
- Java之接口与工厂详解二(附源码)
- C++中的接口与实现
- C++中的接口与实现
- C++中的接口与实现
- Ext FormPanel中的ComboBox为什么声明失效,全部变成了文本框,该怎么处理
- 第十三周工作总结
- OCP 1Z0 051 119
- java工作流插件
- 获取ApplicationContext的几种模式
- ThinkInJava中的接口与工厂
- 机器学习笔记——K-means
- Jquery中设置模板绑定数据的方法
- 环的入口结点检测
- 数据库中索引的作用
- java JMenu--
- Oracle Patchset v11203
- Palindrome Partitioning
- IOS 单元测试