小白谈谈工厂模式

工厂模式分类

简单工厂模式

简单工厂模式是属于创建型模式,又叫做静态工厂方法模式
实例化对象的时候不再使用 new,而是根据用户的条件来实例化相关的类。对于客户端来说,去除了具体的类的依赖。只需要给出具体实例的描述给工厂,工厂就会自动返回具体的实例对象。

代码实现:
定义一个接口,表示时速这一性质

public interface Run {

    public void run();
}

定义三个类具体实现时速这一接口

public class Car implements Run{

    @Override
    public void run() {
        System.out.println("选的是汽车,时速120");
    }
}
public class Bike implements Run{
    @Override
    public void run() {
        System.out.println("选的是自行车,时速20");
    }
}
public class Train implements Run {
    @Override
    public void run() {
        System.out.println("选的是火车,时速200");
    }
}

定义一个工厂用于创建实例:

public class SimpleFactory {

    //简单工厂,根据需求创建对象
    public static Run create(int speed){
        Run run = null;
        if(speed > 120){
            run = new Train();
        }else if(speed > 20 && speed <= 120){
            run = new Car();
        }else{
            run = new Bike();
        }
        return run;
    }
}

客户端代码:

public class Customer {

    public static void main(String[] args) {

        System.out.println("当我想要享受时速200的感觉");
        int speed;
        speed = 200;
        Run choose = SimpleFactory.create(speed);
        choose.run();

        System.out.println("当我想要享受时速20的感觉");
        speed = 20;
        Run choose1 = SimpleFactory.create(speed);
        choose1.run();

        System.out.println("当我想要享受时速100的感觉");
        speed = 100;
        Run choose2 = SimpleFactory.create(speed);
        choose2.run();
    }
}

分析:我们无需提供具体的子类类名,只需要提供条件即可得到相应的实例对象。这样的话,当子类的类名更换或者增加子类时我们都无需修改客户端代码,只需要在简单工厂类上增加一个分支判断代码即可。
不过这种方式仍然存在弊端,在实例对象要实现很多不同的方法的话,我们还需要在工厂类中添加代码,从而导致这个简单工厂类代码臃肿、耦合性高。

工厂方法模式

工厂方法模式是对简单工厂模式进一步的解耦,因为在工厂方法模式中是一个子类对应一个工厂类,而这些工厂类都实现于一个抽象接口。这相当于是把原本会因为业务代码而庞大的简单工厂类,拆分成了一个个的工厂类,这样代码就不会都耦合在同一个类里了。

实现代码:
首先定义一个工厂接口:

public interface Factory {

    public Run create();
}

同样的定义一个接口,表示时速这一性质

public interface Run {

    public void run();
}

同简单工厂模式一样实现时速这接口的具体实现:

public class Bike implements Run {

    @Override
    public void run() {
        System.out.println("时速20");
    }
}
public class Train implements Run {
    @Override
    public void run() {
        System.out.println("时速200");
    }
}
public class Car implements Run{

    @Override
    public void run() {
        System.out.println("时速120");
    }
}

定义三个实体的工厂

public class BikeFactory implements Factory {
    @Override
    public Run create() {
        System.out.println("选择的是bike");
        return new Bike();
    }
}
public class CarFactory implements Factory{

    @Override
    public Run create() {
        System.out.println("选择的是car");
        return new Car();
    }
}
public class TrainFactory implements Factory {
    @Override
    public Run create() {
        System.out.println("选择的是train");
        return new Train();
    }
}

客户端代码:

public class Customer {

    public static void main(String[] args) throws Exception{

        // 使用反射机制实例化工厂对象
        Factory bikeFactory = (Factory)Class.forName("com.ctb.factorymethod.BikeFactory").newInstance();
        Factory carFactory = (Factory)Class.forName("com.ctb.factorymethod.CarFactory").newInstance();
        Factory trainFactory = (Factory)Class.forName("com.ctb.factorymethod.TrainFactory").newInstance();

        // 通过工厂对象创建相应的实例对象
        Run bike = bikeFactory.create();
        Run car = carFactory.create();
        Run train = trainFactory.create();

        bike.run();
        car.run();
        train.run();

    }
}

分析:调用者想创建一个对象,只要知道其名称就可以了。该模式扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。封装了产品的具体实现,调用者只关心产品的接口。但是每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖

抽象工厂模式

基于上面的案例,不再只是选择出行工具,而是要加上选择的食物类型时,就好比我们去旅游,会给我们一个套餐:出行工具+食物类型,这样一个套餐统称为一个族,通过下面的新的方式进行实现:

实现代码:
首先定义一个抽象工厂类(套餐样板),抽象工厂类包括食物和交通工具:

public abstract class AbstractFactory {
    abstract Food createdFood();
    abstract Tool createdTool();
}

定义一个食物的抽象类:

public abstract class Food {
    abstract void printName();
}

定义一个交通工具的抽象类:

public abstract class Tool {
    abstract void run();
}

具体实现食物抽象类:

public class Chicken extends Food {
    @Override
    void printName() {
        System.out.println("烤鸡");
    }
}
public class Steak extends Food {
    @Override
    void printName() {
        System.out.println("牛扒");
    }
}
public class Vegetables extends Food{
    @Override
    void printName() {
        System.out.println("蔬菜");
    }
}

具体实现交通工具的类:

public class Bike extends Tool {
    @Override
    void run() {
        System.out.println("时速20");
    }
}
public class Car extends Tool {
    @Override
    void run() {
        System.out.println("时速120");
    }
}
public class Train extends Tool {
    @Override
    void run() {
        System.out.println("时速200");
    }
}

这时就可以定义一个族了,就是这个案例中的套餐
首先定义一个最贵的:

public class Expensive extends AbstractFactory {
    @Override
    Food createdFood() {
        return new Steak();
    }

    @Override
    Tool createdTool() {
        return new Train();
    }
}

再定义一个最便宜的:

public class Cheapest extends AbstractFactory {
    @Override
    Food createdFood() {
        return new Vegetables();
    }

    @Override
    Tool createdTool() {
        return new Bike();
    }
}

然后就是顾客的选择:

public class Customer {

    public static void main(String[] args) {

        //豪华大餐
        AbstractFactory abstractFactory = new Expensive();
        Tool tool = abstractFactory.createdTool();
        Food food = abstractFactory.createdFood();
        tool.run();
        food.printName();

        //穷游
        AbstractFactory abstractFactory1 = new Cheapest();
        Tool tool1 = abstractFactory.createdTool();
        Food food1 = abstractFactory.createdFood();
        tool1.run();
        food1.printName();

    }
}

同样的,你们也可以参照这个代码,创建一个大家都合适的套餐,然后在顾客 调用的时候只需要改变实例化的套餐模板就可以了

分析:工厂模式符合OCP原则,也就是开闭原则,在我们增加一类产品的时候,同时在增加一个工厂就可以解决这个问题,不需要我再来实现,具有高内聚,低耦合的特点,只需要提供product Interface和concrete factory就可以产生自己需要的对象和方法。

本文的代码:https://pan.baidu.com/s/1Y3faEUTzPZ5M6bOznu56Ng
提取码:n2no

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值