• 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类表示一段复杂的代码,那么这种方式就允许你在不同类型的游戏中复用这段代码。

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

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

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

  • 相关阅读:
    4.1.7 POD对象
    异常处理
    POJ3167 Cow Patterns [KMP]
    POJ1961 Period [KMP应用]
    POJ2778 DNA Sequence [AC自动机+矩阵]
    HDU2243 考研路茫茫——单词情结 [AC自动机+矩阵]
    POJ2185 Milking Grid [KMP应用]
    POJ2541 Binary Witch [状态压缩]
    ZOJ3430 Detect the Virus [AC自动机]
    POJ2752 Seek the Name, Seek the Fame [KMP]
  • 原文地址:https://www.cnblogs.com/cgy-home/p/11155354.html
Copyright © 2020-2023  润新知