Java设计模式之工厂方法设计模式

更多的关于工厂方法设计模式的内容请移步:http://www.cnblogs.com/chenssy/archive/2013/05/24/3096161.html;
首先我们来了解一下面向对象设计的几个原则:
(1)OCP原则:(open-closed principle)又叫做开闭原则。一个软件的实体应当对拓展开放,对修改关闭。通俗的讲就是,当我们在增加新的功能的时候,应该尽可能地通过增加新的类来增加新的功能,而不是在原有的类的基础上进行修改。这是要注意的。
(2)依赖倒转原则DIP(Dependence Inverse Principle):在以后的编程的过程当中,我们应当尽可能地面向接口编程,而不是面向实现的编程。举一个例子来说明就是:比如我们有来个类,A类和B类。我们有一个方法就是在B类中调用A类,那么B和A之间的依赖关系就很强了。但是,如果我们规定,A类B类都必须实现各自的接口的话,我们就可以减弱A和B之间的依赖关系。从而将面向实现编程转化为面向接口编程。
(3)迪米特法则(LOD:Law of Demeter):只与朋友之间进行通信,而不是与陌生人之间进行通信。这是什么意思呢?比如我们有一个类A,我们尽可能地避免A和其它的类发生关系。这有利于A的解耦。如果一个类其它的很多的类都发生了关系,那么以后对这个类的功能的拓展就会产生不利影响。这是要注意的。其实这些和我们的社会关系都是互相对象的。我们的社会其实就是一个讲究“分工”与“合作”的社会。只有分工明确了,我们的社会才能更好的发展。	
/*接口是实现多重继承的重要的途径,而生成遵循某个接口的对象的典型的方式是工厂方法设计模式。这与直接调用
* 构造器不同。我们在工厂对象上调用是创建的方法,而该工厂对象将生成接口的某个可以实现的对象。理论上
* 通过这种方式,我们的代码将完全与接口的实现分离。这就使我们可以透明地将某个实现替换为另外的一个实现
* */
interface  Service{
    void method1();
    void method2();
}

interface  ServiceFactory{
//    调用的是创建方法
  Service getService();
}

//实现接口的一个对象
class Implementation1 implements  Service{
    Implementation1(){}
    @Override
    public void method1() {
        System.out.println("Implementation1 method1");
    }

    @Override
    public void method2() {
        System.out.println("Implementation1 method2");

    }
}

//工厂生成对象
class Implementation1Factory implements  ServiceFactory{
    @Override
    public Service getService() {
        return new Implementation1();
    }
}

class Implementation2 implements  Service{
    Implementation2(){}
    @Override
    public void method1() {
        System.out.println("Implementation2 method1");
    }

    @Override
    public void method2() {
        System.out.println("Implementation2 method2");
    }
}

class Implementation2Factory implements ServiceFactory{
    @Override
    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());
        serviceConsumer(new Implementation2Factory());
    }

}

最后的输出的结果为:

Implementation1 method1 Implementation1 method2 Implementation2 method1 Implementation2 method2

为什么我们想要添加这种级别的间接性呢?一个常见的原因是想要创建框架。假设你正在创建一个对弈游戏系统,例如在相同的棋盘上下国际象棋和西洋跳棋。程序如下:

interface  Game{
    boolean move();
}

interface  GameFactory{
    Game getGame();
}

class Checkers implements  Game{
    private int moves;
    private static final int MOVES=3;
    @Override
    public boolean move() {
        System.out.println("Checkers move" + moves);
        return ++moves!=MOVES;
    }
}

class CheckerFactory implements  GameFactory{
    @Override
    public Game getGame() {
        return new Checkers();
    }
}
class Chess implements  Game{
    private int moves=0;
    private static final int MOVE=4;
    @Override
    public boolean move() {
        System.out.println("Chess move" + moves);
        return ++moves!=MOVE;
    }
}

class ChessFactory implements  GameFactory{
    @Override
    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 CheckerFactory());
        playGame(new ChessFactory());

    }
}
程序运行的结果为:

Checkers move0
Checkers move1
Checkers move2
Chess move0
Chess move1
Chess move2
Chess move3

其实,如果使用了匿名内部类的创建的方式,你就可以看到更加优雅的工厂的实现的模式。代码如下:

/*在本例中,一般情况下,我们只需要创建单一的工厂对象,因此在本例中它被创建为Service实现中的一个static域。
* */
interface  Service{
    void method1();
    void method2();
}

interface  ServiceFactory{
//    调用的是创建方法
  Service getService();
}

//实现接口的一个对象
class Implementation1 implements  Service{
//    将构造器私有化,防止外部进行创建对象
  private Implementation1(){}
    @Override
    public void method1() {
        System.out.println("Implementation1 method1");
    }

    @Override
    public void method2() {
        System.out.println("Implementation1 method2");
    }
//创建了一个匿名内部类:并且这个域是使用了static 来进行修饰的。用static来进行修饰的域
//    只会被加载一次。
     public static ServiceFactory  factory=new ServiceFactory(){
         @Override
         public Service getService() {
             return new Implementation1();
         }
     };
}



class Implementation2 implements  Service{
//    将构造器私有化,防止外部创建对象。
    private Implementation2(){}
    @Override
    public void method1() {
        System.out.println("Implementation2 method1");
    }

    @Override
    public void method2() {
        System.out.println("Implementation2 method2");
    }

    public static ServiceFactory factory=new ServiceFactory() {
        @Override
        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);
        serviceConsumer(Implementation2.factory);

    }
}
对于另外的一个程序,也可以使用匿名内部类来进行创建:

/*如果Games表示的是一段很复杂的内容,那么这种方式允许你在不同类型的游戏中服用这段代码*/
interface  Game{
    boolean move();
}

interface  GameFactory{
    Game getGame();
}

class Checkers implements  Game{
    private Checkers(){}
    private int moves;
    private static final int MOVES=3;
    @Override
    public boolean move() {
        System.out.println("Checkers move" + moves);
        return ++moves!=MOVES;
    }
    public static GameFactory factory=new GameFactory() {
        @Override
        public Game getGame() {
            return new Checkers();
        }
    };
}


class Chess implements  Game{
    private int moves=0;
    private static final int MOVE=4;
    @Override
    public boolean move() {
        System.out.println("Chess move" + moves);
        return ++moves!=MOVE;
    }
    
    public static GameFactory factory=new GameFactory() {
        @Override
        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);

    }
}

其实,在这里我还想补充的一点就是:当使用工厂化方法来创建对象的时候,我们一般是不关心对象是如何被创建的。只要你 传入合适的参数,那么我们就可以创建对象。但是,需要创建的类比较多的时候,那么这个类就显得有点复杂了,并且难于维护了。这是要注意。这个工厂方法设计模式与简单工床模式相比,虽然前符合了OCP原则,但是可以明显看出前者需要的类比后面的简单工厂模式的类要多。所以在类的数量很多的时候,那么这个体系显得难免就有些复杂了。这是要注意的。其实在一般的项目开发当中,我们一般会使用简单工厂模式。

最后我们来看一下工厂方法模式和简单工厂模式之间的区别:

主要是从结构复杂度,代码复杂度,还有客户端管理复杂度来进行比较:


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱coding的同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值