9.9 接口与工厂

接口是实现多重继承的途径,而生成遵循某个接口的对象的典型方式就是工厂方法设计模式。这与直接调用构造器不同,我们在工厂对象上调用的是创建方法,而该工厂对象将生成解耦的某个实现的对象。理论上,通过这种方式,我们的代码将完全与接口的实现分离,这就使得我们可以透明地将某个实现替换为另一种实现。下面的实例展示了工厂方法的结构:
//: interfaces/Factories.java

interface Service {
    void method1();
    void method2();
}

interface ServiceFactory {
    Service getService();
}

class Implementation1 implements Service {
    implementation1() {} // Package access
    public void method1() {
        System.out.print("Implementation1 method1");
    }
    public void method2() {
        System.out.print("Implementation1 method2");
    }       
}

class Implementation2 implements Service {
    implementation2() {} // Package access
    public void method1() {
        System.out.print("Implementation2 method1");
    }
    public void method2() {
        System.out.print("Implementation2 method2");
    }       
}

class Implementation2Factory implemnts ServiceFactory {
    public service getService() {
        return new Implementation2();
    }
}

public class Factories {
    public static void serviceConsumer(ServiceFactory fact){
        serviceConsumer(new Implementation1Factory());
        // Implementations are completely interchangeable;
        serviceConsumer(new Implementation2Factory());
    }
}/* Output:
Implementation1 method1
Implementation1 method2
Implementation2 method1
Implementation2 method2
*///:~

如果不是工厂方法,你的代码就必须在某处制定将要创建的Service的确切类型,以便调用合适的构造器。
为什么我们想要添加这种额外级别的间接性呢?一个常见的原因是想要创建框架:加入你正在创建一个博弈游戏系统,例如,在相同的棋盘上下国际象棋和西洋跳棋:
//:interfaces/Games.java
// A Game framework using Factory Methods

package July_9;

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() {
        System.out.println("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() {
        System.out.println("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 move0
Checkers move1
Checkers move2
Chess move 0
Chess move 1
Chess move 2
Chess move 3
*///:~

如果Games类表示一段复杂的代码,那么这种方式就允许你在不同类型的游戏中复用这段代码。

“确定接口是理想选择,因而应该总是选择接口而不是具体的类。”这其实是一种引诱。

任何抽象性都应该是应真正的需求而产生的。当必须时,你应该重构接口而不是导出添加额外级别的间接性,并由此带来的额外的复杂性。

恰当的原则应该是有限选择类而不是接口。从类开始,如果接口的必须行变得非常明确,那么就进行重构。

转载于:https://www.cnblogs.com/cgy-home/p/11155354.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值