Java中的设计模式-一(简单工厂模式)

130 阅读3分钟

释义

  工厂模式,那就和工厂有些许关系,工厂是用来干什么的,生产产品的,那在设计模式中,工厂模式也正如字面含义一样,可以生产一些东西。在java中,工厂模式一般都是用来实例化对象模式了,是用工厂方法代替new操作的一种模式。

案例

  编写一个超市打折促销的计算方式,有三种计算方式,原价、打折、满减。我们根据该需求设计一个程序,如下。

public static void main(String[] args) {  
    Scanner scanner = new Scanner(System.in);  
    int s = Integer.parseInt(scanner.nextLine());  
    double price = 200;  
    int num = 2;  
    double result = 0;  
    //1:原价,2:打8折,3:满300减去100  
    switch (s) {  
        case 1:  
        result = price * num;  
        break;  
    case 2:  
        result = price * num * 0.8;  
        break;  
    case 3:  
        double total = price * num;  
        if (total >= 300) {  
        total -= Math.floor(total / 300) * 100;  
        }  
        result = total;  
        break;  
    }  
    System.out.println("最终售价为:" + result);  
}

  如代码所示,三种情况我们写一个switch对不同情况做不同计算即可,这样看着好像也没什么问题,但是如果后面再加几种计算方式,我们就需要在继续拼接switch了。这样一旦活动有所更改,或者增加,都需要修改这个类,所有的业务,计算都在一个类中。这样实在不是很符合开发的设计理念。
  我们应该把计算放到后面,在mvc模式的开发下,计算应该是service做的事情。而switch的选择,是视图所需要做的工作。而且最好是把所有的促销模式一一做一次封装,这样以后如果对一种活动做修改,那么就不会改动其他的活动。代码做如下改动

public class CashNormal{  
 
    public double acceptCash(double price, int num) {  
        return price * num;  
    }  
}
public class CashRebate{  
    //折扣值
    private double zk;  

    public CashRebate(double zk) {  
        this.zk = zk;  
    }  
 
    public double acceptCash(double price, int num) {  
        return price * num * zk;  
    }  
}
public class CashReturn{  
    //满减需要达到额度
    private double m;  
    //减去数值
    private double j;  
    public CashReturn(double m, double j) {  
        this.m = m;  
        this.j = j;  
    }  

    public double acceptCash(double price, int num) {  
        double total = price * num;  
        if (total >= m) {  
            total -= Math.floor(total / m) * j;  
        }  
        return total;  
    }  
}
double result = 0;
switch (s){  
    case 1:  
        CashNormal c1 = new CashNormal();  
        result = c1.acceptCash();
        break;  
    case 2:  
        CashRebate c2 = new CashRebate(0.8);  
        result = c2.acceptCash();
        break;  
     case 3:  
        CashRebate c3 = new CashRebate(300, 100);  
        result = c3.acceptCash();
        break;  
}
System.out.println("最终售价为:" + result);  

  经过如上操作,把计算业务单独封装类,后续对其中一种算法做修改就可以减少对其他算法的影响。但是对于业务来说,不管是原价,还是打折,都是属于一种销售计价方式,这时候我们可以用继承父类的方式,使用多态的特性做个修改。创建CashSuper类,CashNormal、CashRebate、CashReturn类都继承该父类。再将switch做修改。

public abstract class CashSuper {  
    public abstract double acceptCash(double price, int num);  
}
CashSuper cs = null;  
switch (s){  
    case 1:  
        cs = new CashNormal();  
        break;  
    case 2:  
        cs = new CashRebate(0.8);  
        break;  
    case 3:  
        cs = new CashReturn(300, 100);  
        break;  
}  
System.out.println("最终售价为:" + cs.acceptCash());  

  这里就可以使用工厂模式特性再做一次封装,switch中根据不同情况产生三个对象,其实正是工作需要做的事情,我们把这一段逻辑单独放一个CashFactory的类中。

public class CashFactory {  
  
    public static CashSuper getSf(int s){  
        CashSuper cs = null;  
        switch (s){  
            case 1:  
                cs = new CashNormal();  
                break;  
            case 2:  
                cs = new CashRebate(0.8);  
                break;  
            case 3:  
                cs = new CashReturn(300, 100);  
                break;  
        }  
        return cs;  
    }  
}
public static void main(String[] args) {  
    Scanner scanner = new Scanner(System.in);  
    int s = Integer.parseInt(scanner.nextLine());  
    CashSuper cs = CashFactory.getSf(s);  
    double result = cs.acceptCash(200, 2);  
    System.out.println(result);  
}

  简单工厂模式在设计模式中算比较容易理解的模式,这里直接写出例子就可以看出该模式在这个需求中起到的作用。客户端不再进行判断,也不再关注计算公式。只需要知道需要的促销方式,传送给工厂,工厂根据类型去生产出一个对应的计算对象。再通过多态使用父类对象进行调用子类的具体实现方法。 image.png