引申复习面向对象的设计的六大原则,一些设计模式中就体现了这类原则
单一职责:一个合理的类功能应该只有一个,消除耦合减少需求变化对代码的修改
开闭原则:一个类应该对扩展开启,对修改关闭。降低程序模块之间的耦合度,增加扩展性
里氏替换原则:子类应该能替换基类。 能够很好的实现功能的调整和升级,并且不影响客户端调用
依赖倒换原则:设计依赖于抽象而不是依赖于具体化。
接口隔离原则:划分接口应该单一细致,让系统容易实现重构,对接口修改时影响较少。
迪米特法则:一个类尽可能少的去了解其他对象
这些原则其实最后的目的是为了程序中模块分工明确,便于升级和调整。
工厂模式:实例化对象,用工厂方法代替new操作,将实现类和对象的创建统一管理和控制,从而将调用者和实现类解耦。
工厂模式也分为三种,简单工厂模式(静态工厂模式)、工厂方法模式,抽象工厂模式
一、简单抽象模式(静态抽象模式)
1、UML类图
动物产品可以有Cat、Pig、Dog 客户端来生成产品时需要与每一个具体的产品产生联系,比如 Animal cat = new Cat();这样 对象的生成和控制全在客户端client。 不便于管理,那么我们可以将对象的生成交给第三方来管理。 客户端需要产品 只要通知一个组件 我需要什么对象,组件返回相应对象满足客户端;那么对象的生成相对于客户端透明, 便于统一管理。这就是简单抽象模式。
2、产品类: Cat 、Pig、Dog实现Animal接口
package factory.simple;
public interface Animal {
public void say();
}
package factory.simple;
public class Cat implements Animal {
public void say() {
System.out.println("喵喵喵");
}
}
package factory.simple;
public class Dog implements Animal {
public void say() {
System.out.println("汪汪汪");
}
}
package factory.simple;
public class Pig implements Animal {
public void say() {
System.out.println("哼哼哼");
}
}
3、工厂类:SimpleFactory
package factory.simple;
public class SimpleFactory01 {
//第一种简单工厂模式
public static Animal creatAnimal(String type){
if("cat".equals(type)){
return new Cat();
}else if("pig".equals(type)){
return new Pig();
}else{
return null;
}
}
//第二种简单工厂模式
public static Animal creatCat(){
return new Cat();
}
public static Animal creatPig(){
return new Pig();
}
}
4、客户端
package factory.simple;
public class Client1 {
public static void main(String[] args) {
Animal cat = SimpleFactory01.creatAnimal("cat");
cat.say();
Animal pig = SimpleFactory01.creatAnimal("pig");
pig.say();
Animal cat2 = SimpleFactory01.creatCat();
cat2.say();
Animal pig2 = SimpleFactory01.creatPig();
pig2.say();
}
}
5、总结:客户端在需要动物产品时 只需要向SimpleFactory通知需要什么对象就能得到满足。实现了对象的生成与统一管理交给了工厂SimpleFactory。实现了分工。
优点:简单工厂模式实现简单。
缺点:对于新产品的添加需要对已存在的工厂代码修改,违反了开闭原则。
二、工厂方法模式
通过上面的建档工厂模式,当我们需要增加一个新的产品(alpaca羊驼)时,我们需要在原工厂内增加逻辑生成新产品,这违背了开闭原则,对扩展开放,对修改关闭。这显然不合理,那么我们可以通过工厂方法模式来解决这个问题。 我们可以将工厂类进行拆分。将产品和工厂类一一对应,那么我们需要增加新的产品时,只需要增加相应的产品类和工厂类就可以解决了。
1、UML类图
2、产品类(与简单工程类一致)
3、工厂类
package factory.method;
import factory.method.Animal;
/**
* 工厂方法模式
*/
public interface MethodFactory {
Animal create();
}
package factory.method;
public class CatFactory implements MethodFactory {
public Animal create() {
return new Cat();
}
}
package factory.method;
public class PigFactory implements MethodFactory {
public Animal create() {
return new Pig();
}
}
4、客户端
package factory.method;
public class Client {
public static void main(String[] args) {
Animal cat = new CatFactory().create();
cat.say();
Animal pig = new PigFactory().create();
pig.say();
}
}
5.总结:当需要新增加其他产品时,只需要增加产品类、和产品对应的工厂类。不需要对已存在的工厂类做修改,符合的开闭原则。
优点:符合开闭原则,对扩展支持良好
缺点:增加了类,增加了类的管理
三、抽象工厂模式
工厂方法模式很好的解决了简单工厂模式遗留下的扩展问题。但并不是工厂方法就是完美的存在这种情况:当我们需要同种产品存在差异时,比如我需要一个很肥的猫,需要一个瘦的猫。 如果使用抽象工厂方法模式,那么需要再增加肥的 和瘦的对应的商品类 并且增加对应的工厂类。
1、UML类图
2.产品类
package factory.abstractfactory;
public interface Animal {
public void say();
}
package factory.abstractfactory;
public interface BigAnimal extends Animal {
}
package factory.abstractfactory;
public interface SmallAnimal extends Animal {
}
package factory.abstractfactory;
public class BigCat implements BigAnimal {
public void say() {
System.out.println("肥猫喵喵喵");
}
}
package factory.abstractfactory;
public class SmallCat implements BigAnimal {
public void say() {
System.out.println("瘦猫嗷嗷嗷");
}
}
3、工厂类
package factory.abstractfactory;
public interface AbstractFactory {
public Animal createBig();
public Animal createSmall();
}
package factory.abstractfactory;
public class CatFactory implements AbstractFactory{
public Animal createBig() {
return new BigCat();
}
public Animal createSmall() {
return new SmallCat();
}
}
4、客户端
package factory.abstractfactory;
public class Client {
public static void main(String[] args) {
Animal bigCat = new CatFactory().createBig();
Animal smallCat = new CatFactory().createSmall();
bigCat.say();
smallCat.say();
}
}
5.总结:抽象工厂类在 工厂方法的基础上对产品和产品的工厂进行再次的抽象分类。 抽象分为建为约束,那么就只能建立类似的产品进行扩展,增加了约束条件。
总结:三种工厂类 没有必须使用哪一种。 根据具体情况选择使用