设计原则
要依赖抽象,不要依赖具体类
这条原则有一个正式的名字:“依赖倒置原则”。这个原则的含义是:不要让高层的组件去依赖低层的组件,而且,这些组件,都应该是依赖于某一个抽象。
设计模式
工厂模式
工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到了子类。
这句话要加粗:工厂方法让类把实例化推迟到了子类
通常,我们在实例化一个对象的时候,都是直接的进行new操作,但是这样会带来这样的问题,如果我们需要根据需要(输入)的不同来新建不同的子类对象,就会产生下面的代码:
myClass mc = null;
if(type.equals("classA")){
myClass = new ClassA();
}else if(type.equals("classB")){
myClass = new ClassB();
}else if(type.equals("classC")){
myClass = new ClassC();
}
//对myClass的其他操作
中间if判断语句很容易产生需求的变化,而这时如果要进行改动就需要对这段代码进行修改,还记得之前的一个设计原则嘛:找出程序中会变化的方面,然后将其和固定不变的方面相分离。
我们还是拿书上的例子来:
披萨店需要做一个自动化披萨机,首先对于每种披萨都有不同的制作流程,披萨制作出来后,需要对披萨进行烘烤、切片、装盒。
下面是基本的代码:
Pizza orderPizza(String type){
Pizza pizza = null;
if(type.equals("cheese")){
pizza = new CheesePizza();
}else if(type.equals("greek")){
pizza = new GreekPizza();
}
pizza.bake();
pizza.cut();
pizza.box();
}
正如上面所说,根据type去new不同的Pizza这部分很容易发生改变,因为pizza的类型是会增加的,而且销量不好的pizza可能会直接从菜单中撤掉!
那么我们可以把这个方法独立到另外的类中,这样如果需要对pizza的种类进行变化就不需要对orderPizza所在的类进行修改了。
我们可以这样做:
public class SimplePizzaFactory{
public static Pizza createPizza(String type){
Pizza pizza = null;
if(type.equals("cheese")){
pizza = new CheesePizza();
}else if(type.equals("greek")){
pizza = new GreekPizza();
}
return pizza;
}
}
有了这个造pizza的”工厂”,我们就可以对orderPizza进行下面的修改了:
public class PizzaStore{
SimplePizzaFactory factory;
public PizzaStore(SimplePizzaFactory factory){
this.factory = factory;
}
public Pizza orderPizza(String type){
Pizza pizza = factory.createPizza(type);
pizza.bake();
pizza.cut();
pizza.box();
}
}
请注意:这种编程方法(也叫简单工厂)其实并不是一种设计模式,而是一种编程习惯。还记得工厂模式的定义嘛:工厂方法让类把实例化推迟到了子类
下面这个例子才是真正的工厂模式的:
现在披萨店有了各种加盟店。对不同的加盟店有不同的披萨菜单,这时候我们就需要更多的类加入这个系统。
下面是披萨店的工厂方法:
public abstract class PizzaStore{
public Pizza orderPizza(String type){
Pizza pizza = createPizza(type);
pizza.bake();
pizza.cut();
pizza.box();
}
protected absract Pizza createPizza(String type);
}
上面这个类就是作为不变的部分,是所有披萨加盟店必须继承的类。
下面分别是纽约店和芝加哥店的orderPizza方法:
public class NYPizzaStore extends PizzaStore{
Pizza createPizza(String type){
Pizza pizza = null;
if(type.equals("cheese")){
pizza = new CheesePizza();
}//其他种类的Pizza
return pizza;
}
}
public class ChicagoPizzaStore extends PizzaStore{
Pizza createPizza(String type){
Pizza pizza = null;
if(type.equals("greek")){
pizza = new GreekPizza();
}//其他种类的Pizza
return pizza;
}
}
看一下这个模式是怎么工作的:
如果你需要在纽约店定一个芝士披萨:
首先你需要有一个店:PizzaStore nyPizzaStore = new NYPizzaStore();
然后下芝士披萨的订单:nyPizzaStore.orderPizza(“cheese”);
这时候,系统内部会调用createPizza方法: Pizza pizza = createPizza(“cheese”);
再经过pizza.bake();pizza.cut();pizza.box();处理后,你的披萨就出炉啦!
当然,我们还需要披萨这个类。再次就不赘述。
下面是这个例子的UML类图: