`

工厂设计模式和单例子的设计模式

阅读更多
一、工厂模式
1.简单工厂模式
也叫静态工厂模式,一般是产品的继承类或是接口的实现,如司机开多个车子的例子。
//接口
public Interface Car{
     public void driver();
}
//定义接口的实现类
public class QQCar implements Car{
public void driver(){
sysout("QQ driver");
}
}

public class BaoMaCar{
public void driver(){
sysout("BaoMa driver");
}
}
//定义工厂类
public class Driver{
public static final String QQ_CAR = "QQCar";
public static  final String BAOMA_CAR="BaoMaCar";

public static Car productCar(String name){
if(name.equalsIgnoreCase("QQCar"){
return new QQCar();
}
if(name.equalsIgnoreCase("BaoMaCar"){
return new BaoMaCar();
}

}
}
//调用工厂创建所需对象
public static void main(String[] args){
Car qqCar = Driver.productCar(Driver.QQ_CAR);
qqCar.driver();
}
总结:简单工厂模式就是达到老板告诉司机我坐QQ车还是做其他车,其余的都交给司机去做。main方法调用出就相当于是老板下达命令。
     优点:工厂类需要返回抽象的产品类型即Car。
          该模式避免了直接创建产品对象的责任。而仅仅是消费该产品就可以了。
     缺点:当添加了一个新的车时,虽然新的调用处置需要告诉司机开心添加的车就可以了,但是工厂类需要添加对应开新车的业务逻辑判断。这样就违背了开闭原则。
          新添加车时工厂类是被动的。这样的工厂类被称为全能类。所有车都由一个司机管理会把司机类坏的。

2.工厂方法模式
//注:渴望某个方法被子类实现那么父类的这个方法就不能定义成static和final的。
工厂方法模式去掉了简单工厂模式的static,这样使得它可以被子类继承,这样父工厂的压力就可以由子工厂进行分担了。
组成部分:
a.抽象工厂,子工厂必须继承或是实现父类。与应用程序无关。
b.子工厂,它包含与具体业务逻辑相关的代码。有应用程序调用以创建具体的产品。
c.抽象产品
d.具体产品角色

例子:
//抽象产品和具体产品如上
//抽象工厂
public interface Driver{
public Car driverCar();
}
//抽象工厂的子类,一个子类管理一辆车
public class QQDriver implements Driver{
public Car driverCar(){
return new QQCar();
}
}
//抽象工厂的子类,一个子类管理一辆车
public class BaoMaDriver implements Driver{
public Car driverCar() {
return new BaoMaCar();
}
}

//爆发户来了,即在main方法中调用。
public static void main(String[] args){
Car qqCar = new QQDriver().driver();
qqCar.driver();
}
优点:这样当添加新的汽车时就不需要修改以前的代码,而是直接安装抽象工厂和抽象产品约定的合同来生成就可以被客户端调用了.符合开闭原则。
     相当于给原来的司机分配了几个属下去管理车。
缺点:当产品多时会出现非常多与之对应的实现工厂。

总结:可以将简单工厂模式与工厂方法模式结合使用。让一个子工厂管理多个产品。
     当客户不需要知道对象的创建过程,或根本不需要知道调用哪个对象。或对象存在变动的可能使用工厂方法模式。

思考:
简单工厂模式与工厂方法模式真正的避免了代码的改动了?没有。在简单工厂模式中,
新产品的加入要修改工厂角色中的判断语句;而在工厂方法模式中,要么将判断逻辑留在抽
象工厂角色中,要么在客户程序中将具体工厂角色写死(就象上面的例子一样)。而且产品
对象创建条件的改变必然会引起工厂角色的修改。
面对这种情况,Java 的反射机制与配置文件的巧妙结合突破了限制——这在Spring 中
完美的体现了出来。

3.抽象工厂模式
产品家族:位于不同产品等级结构中,功能相关联的产品组成的家族。
QQ车:qq商务车、qq运动车
BaoMa车:BaoMa商务车、BaoMa运动车
则qq运动车和BaoMa运动车就算是运动车家族。

组成:
a.抽象工厂
b.具体工厂
c.抽象产品
d.具体产品

实例
//抽象工厂
public Interface AbstractFactory{
public ProductA productA();
public ProductB productB();
}
//抽象工厂子类生产2代家族
public class Product2Factory implements AbstractFactory{
public ProductA productA(){
    return new ProductA2();
}
public ProductB productB(){
    return new ProductB2();
}
}
//抽象工厂子类生产1代家族
public class Product1Factory implements AbstractFactory{
public ProductA productA(){
    return new ProductA1();
}
public ProductB productB(){
    return new ProductB1();
}
}

调用处
public static void main(String[] args){
ProductA productA1 = Product1Factory.productA();
//执行productA1的方法
}


//使用工厂类是为了提高解耦,防止出现骨牌效应

二、单例模式
1.饿汉式单利模式
public class SingleTone{
private SingleTone instance = new SingleTone();//单例实例

private SingleTone(){} //防止外部直接创建对象

//获取单利的入口
public static  SingleTone getInstance(){
return instance;
}
}

2.懒汉式单利模式

public class SingleTone{
private SingleTone instance = null;//单例实例

private SingleTone(){} //防止外部直接创建对象

//获取单利的入口
public static synchronized SingleTone getInstance(){
if(instance == null){
instance = new SingleTone();
}
return instance;
}
}

上面的这种模式效率比较低,可以采用双检索的方式。
public class Singleton{  
    private static Singleton single;    //声明静态的单例对象的变量   
   private Singleton(){}    //私有构造方法    
    
    public static Singleton getSingle(){    //外部通过此方法可以获取对象     
     if(single == null){      
        synchronized (Singleton.class) {   //保证了同一时间只能只能有一个对象访问此同步块         
             if(single == null){       
                single = new Singleton();           
        }     
       }  
    }    
     return single;   //返回创建好的对象    
}  
}


注:如果是J2EE服务器是多servlet引擎或是分布式的环境中就要注意单例模式的使用

让单例可以串行话
public final class Singleton implements Serializable{
private Singleton () { }
private static final Singleton INSTANCE = new Singleton ();
public static Singleton getInstance() { return INSTANCE; }
private Object readResolve() throws ObjectStreamException {
return INSTANCE;
}
}
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics