工厂模式

概述:

     工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式。工厂模式主要有3种,有简单工厂、工厂方法、抽象工厂。下面我们以“美女出门,穿衣打扮”为例子进行说明。

一、简单工厂模式

      工厂类根据所传的参数决定创建那个实体。美女根据出门要办的事,决定穿那件衣服,比如出去约会,需要穿个裙子;如果去运动,那就那件运动装。

//定义一个衣服接口,不同衣服都需要实现该接口(有一个穿戴的方法)
public interface SingleClothes {
    public void wear();
}
//定义个裙子实体
public class Skirt implements SingleClothes {
    @Override
    public void wear() {
        System.out.println("我要约会,我想穿裙子");
    }    
}

//定义一个运动服
public class SportSuit implements SingleClothes {
    @Override
    public void wear() {
        System.out.println("我要跑步,需要运动装");    
    }
}
//定义一个工厂(根据参数生成对应的实体)
public class ClothesFactory {
    public SingleClothes getClothes(String clothes){
        if("skirt".equals(clothes)){
            return new Skirt();
        }else if("sportSuit".equals(clothes)){
            return new SportSuit();
        }
        return null;
    }
}

      此时我们要根据具体事件生产对应的实体类,代码如下

public class SingleClient {
    public static void main(String[] args) {
        ClothesFactory factory = new ClothesFactory();
        SingleClothes skirt =  factory.getClothes("skirt");
        skirt.wear();
        SingleClothes sportSuit = factory.getClothes("sportSuit");
        sportSuit.wear();
    }
}

     执行结果如下:

       

   这就是所谓的简单工厂模式,但从例子我们可以看出,如果添加新的衣服类型,那必须修改ClothesFactory 的方法。这种模式不符合“开闭原则”(对扩展开放;对修改封闭)

二、工厂方法模式

   该模式中,每个产品由指定的工厂生产,所有工厂都继承或实现一个抽象工厂。基于开闭原则,我们对简单工厂进行改造。

//定义一个抽象工厂
public interface MethodFactory {
    public SingleClothes getClothes();
}
//定义裙子工厂
public class SkirtFactory implements MethodFactory {
    @Override
    public SingleClothes getClothes() {
        return new Skirt();
    }
}
//定义运动装工厂
public class SportSuitFactory implements MethodFactory {
    @Override
    public SingleClothes getClothes() {
        return new SportSuit();
    }
}

同样我们需要定义想要的衣服对象

//定义一个衣服接口,不同衣服都需要实现该接口(有一个穿戴的方法)
public interface SingleClothes {
    public void wear();
}

//定义个裙子实体
public class Skirt implements SingleClothes {
    @Override
    public void wear() {
        System.out.println("我要约会,我想穿裙子");
    }    
}

//定义一个运动服
public class SportSuit implements SingleClothes {
    @Override
    public void wear() {
        System.out.println("我要跑步,需要运动装");    
    }
}

  此时我们要根据具体工厂生产对应的实体类,代码如下

public class MethodClient {
    public static void main(String[] args) {
        MethodFactory factory = new SkirtFactory();
        SingleClothes cloths =factory.getClothes();
        cloths.wear();
    }
}

  这里我们生成了一个裙子,执行结果如下

  

  如果我们这些要生成运动装,只需将MethodFactory factory = new SkirtFactory();改成MethodFactory factory = new SportSuitFactory();

  可以看出代码得到一定的优化,当然最重要的是已经解决“开闭原则”,比如我们现在添加新的衣服(旗袍),那我们无需修改上面的代码,只需要添加对应的工厂和对象即可。

//旗袍实体类
public class Cheongsam implements SingleClothes {
    @Override
    public void wear() {
        System.out.println("我是淑女,我想穿旗袍");    
    }
}
//旗袍工厂
public class CheongsamFactory implements MethodFactory {
    @Override
    public SingleClothes getClothes() {    
        return new Cheongsam();
    }
}

   虽然上面解决了“简单工厂”的开闭原则,但每生成一个新产品,都需要一套工厂,比如我出门,我需要穿鞋,此时我需要新建一个抽象鞋工厂,然后再具体实现对应的写工厂(高跟鞋、运动鞋等),这样容易造成工厂泛滥。

 

三、抽象工厂模式

该模式主要用于生产一系列的产品,比如美女出门,需要选择对应的外套和鞋子。那这些产品可以由一个工厂配套产生,这样可以有效的解决“工厂方法模式”工厂泛滥的问题。这就是所谓的抽象工厂模式。

这里我产生两套产品,分别是“穿着高跟鞋和裙子去约会”和“穿着运动装和运动鞋去跑步”。首先我们除了定义上面衣服的实体对象,还需要定义鞋子的实体对象。

//定义一个鞋子接口,不同鞋子都需要实现该接口(有一个穿戴的方法)
public interface SingleShoes {
    public void putOn();
}
//定义运动鞋
public class SportShoes implements SingleShoes {
    @Override
    public void putOn() {
        System.out.println("穿着运动鞋去跑步");
    }
}
//定义高跟鞋
public class HighheeledShoes implements SingleShoes {
    @Override
    public void putOn() {
        System.out.println("优雅的踩着高跟鞋");
    }
}

  然后定义一个抽象工厂,该工厂主要用于生产一系列产品(衣服和写)

public interface AbstractFactory {
    public SingleClothes getClothes();
    public SingleShoes getShoes();
}
//定义一个运动装工厂,用于生产运动装和运动鞋
public class SportswearFactory implements AbstractFactory {
    @Override
    public SingleClothes getClothes() {        
        return new SportSuit();
    }

    @Override
    public SingleShoes getShoes() {
        return new SportShoes();
    }
}
//定义一个休闲装工厂,用于生产裙子和高跟鞋
public class LeisureClothesFactory implements AbstractFactory {
    @Override
    public SingleClothes getClothes() {
        return new Skirt();
    }

    @Override
    public SingleShoes getShoes() {
        return new HighheeledShoes();
    }
}

  此时生产对应休闲套装代码如下:

public class AbstractClient {
    public static void main(String[] args) {
        AbstractFactory factory = new LeisureClothesFactory();
        SingleClothes clothes = factory.getClothes();
        clothes.wear();
        SingleShoes shoes = factory.getShoes();
        shoes.putOn();
    }
}

  执行结果如下:

  

   如果要生产别的套装,我们只需将AbstractFactory factory = new LeisureClothesFactory();改成AbstractFactory factory = new SportswearFactory();即可。这就是抽象工厂模式,虽然可以解决工厂泛滥的问题,但这个模式有个问题就是扩展性不好,如果我要新增新产品(帽子),那这些所有跟工厂相关的类就必须修改。

 

PS:曾经实现过跟工厂模式有关的功能:对外接口

 

posted @ 2017-06-07 00:35  开着坦克的瑞兽  阅读(175)  评论(0)    收藏  举报