设计模式
为了重用代码,解耦,让代码更容易被任理解/保证代码可靠性。
1.简单工厂
1.描述:顾名思义,这个模式本身很简单,而且使用在业务模式较简单的情况下。
2.关键点
1.工厂类角色:这是本模式的核心,含有一定的商业逻辑和判断逻辑。在java中它往往由一个具体类实现。
package com.lpw.simple;
// 生产卡车的工厂类
public class TrunkFactory {
// 不管是宝马还是奥迪都是卡车
public static Trunk geTrunk(String message) {
// if("宝马".equals(message)){
// return new BMwTrunk_s();
// }else if ("奥迪".equals(message)) {
// return new AodiTrunk_s();
// }else {
// throw new RuntimeException("没有您要的车,可能还没有创造……");
// }
switch (message) {
case "宝马":
return new BMwTrunk_s();
case "奥迪":
return new AodiTrunk_s();
default:
return null;
}
}
}
2.抽象产品角色:它一般是具体产品继承的父类或者实现的接口。在java中由接口或者抽象类来实现。
package com.lpw.simple;
// 抽象(卡车)
public interface Trunk {
public void run();
}
3.具体产品角色:工厂类所创建的对象就是此角色的实例在java中由一个具体类实现。
package com.lpw.simple;
public class AodiTrunk_s implements Trunk{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("奥迪卡车启动……");
}
}
package com.lpw.simple;
public class BMwTrunk_s implements Trunk{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("宝马卡车启动……");
}
}
3.开闭原则分析简单工厂模式
对扩展开放,对修改封闭一个软件应该通过扩展来实现变化,而不是通过修改已有的代码来实现变化的。
若新增一个大众汽车
package com.lpw.simple;
public class DaZTrunk implements Trunk{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("大宗在运行……");
}
}
就需要修改工厂类,
package com.lpw.simple;
// 生产卡车的工厂类
public class TrunkFactory {
// 不管是宝马还是奥迪都是卡车
public static Trunk geTrunk(String message) {
// if("宝马".equals(message)){
// return new BMwTrunk_s();
// }else if ("奥迪".equals(message)) {
// return new AodiTrunk_s();
// }else {
// throw new RuntimeException("没有您要的车,可能还没有创造……");
// }
switch (message) {
case "宝马":
return new BMwTrunk_s();
case "奥迪":
return new AodiTrunk_s();
case "大众":
return new DaZTrunk();
default:
return null;
}
}
}
所以违反了,开闭原则。
4.缺点
简单工厂模式,违反开闭原则。扩展性差。
2. 工厂方法
1.描述
定义一个创建对象的工厂接口,让子类决定实例化哪一个类,将实际工作交给子类。
2. 关键点
1. 抽象工厂角色:这是工厂方法模式的核心。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。
package com.lpw.methord;
// 抽象工厂
public interface TrunkFactory_M {
public Trunk_M createTrunk();
}
2.具体工厂角色:它包含和具体业务逻辑有关的代码。创建对应的具体产品的对象。在java中它由具体的类来实现。
package com.lpw.methord;
public class AodeTrunkFactory implements TrunkFactory_M{
@Override
public Trunk_M createTrunk() {
// TODO Auto-generated method stub
return new AodiTrunk_M();
}
}
package com.lpw.methord;
public class BmwTrunkFactory implements TrunkFactory_M{
@Override
public Trunk_M createTrunk() {
// TODO Auto-generated method stub
return new BMwTrunk_M();
}
}
3. 抽象的产品角色:它是具体产品继承的父类或者实现的接口。
package com.lpw.methord;
// 抽象(卡车)
public interface Trunk_M {
public void run();
}
4.具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。
package com.lpw.methord;
public class BMwTrunk_M implements Trunk_M{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("宝马卡车启动……");
}
}
package com.lpw.methord;
public class AodiTrunk_M implements Trunk_M{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("奥迪卡车启动……");
}
}
3.问题
工厂方法模式足以应付我们可能遇到的大部分业务需求,但当产品种类非常多的时候回怎么样呢?
4. 分析优缺点
优点:更符合开闭原则:新增一种产品时,只需要增加相应的具体产品和相应的工厂子类即可
符合单一职责原则:每个具体工厂类只负责创建对应的产品。
缺点:在增加一个新产品的时候,需要增加一个产品类和一个具体的子工厂,给系统增加负担的同时,每个工厂生产一种产品,太过单一;
3. 抽象工厂
1.描述
给客户端提供一个借口,可以创建多个产品族中的产品对象
2.关键点
1.抽象工厂角色:这是工厂方法模式的核心,是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。
package com.lpw.abstr;
public interface CarFacory {
// 生产卡车
public Trunk_A produceTrunk();
// 生产轿车
public Sedan produceSedan();
}
2.具体工厂角色:它含有和具体业务逻辑有关的代码。创建对应的具体产品的对象。在java中它由具体的类来实现。
package com.lpw.abstr;
public class BwmFactory implements CarFacory{
@Override
public Trunk_A produceTrunk() {
// TODO Auto-generated method stub
return new BwmTrunk();
}
@Override
public Sedan produceSedan() {
// TODO Auto-generated method stub
return new BwmSedan();
}
}
package com.lpw.abstr;
public class AodiFactory implements CarFacory{
@Override
public Trunk_A produceTrunk() {
// TODO Auto-generated method stub
return new AodiTrunk();
}
@Override
public Sedan produceSedan() {
// TODO Auto-generated method stub
return new AodiSedan();
}
}
3.抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。
package com.lpw.abstr;
// (抽象)轿车
public interface Sedan {
// 轿车的启动方法
public void run();
}
package com.lpw.abstr;
// (抽象)卡车
public interface Trunk_A {
// 卡车对的启动时间
public void run();
}
4.具体产品角色:具体工厂角色所创建的独享就是此角色的实例。在java中由具体的类来实现。
package com.lpw.abstr;
public class AodiSedan implements Sedan{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("奥迪轿车……");
}
}
package com.lpw.abstr;
public class AodiTrunk implements Trunk_A{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("奥迪卡车……");
}
}
package com.lpw.abstr;
public class BwmSedan implements Sedan{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("保存吗轿车在运行……");
}
}
package com.lpw.abstr;
public class BwmTrunk implements Trunk_A{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("宝马卡车在运行……");
}
}
如果工厂的产品来自多个等级结构,则属于抽象工厂模式。
总结:
无论是简单工厂模式,工厂方法模式,还是抽象工厂模式,它们都属于工厂模式,在形式和特点上也是极为相似的,它们的最终目的都是为了解耦。
使用工厂模式时,只需要关心降低耦合度的目的是否达到了。