您的位置:首页 > 编程语言 > Java开发

java设计模式之工厂模式

2018-03-10 13:19 330 查看

反射(java reflection)

在JDK中,主要由以下类来实现java反射机制,这些类都位于java.lang.reflect包中。

1. Class类:代表一个类

2. Constructor类:代表类的构造方法

3. Field类:代表类的成员变量

4. Method类:代表类的方法

工厂模式

工厂模式一般分为简单工厂、工厂、抽象工厂3种情况,属于创建型设计模式。

简单工厂模式:

//定义小汽车接口

public interface ICar{
}


//下面定义高、中、低档具体的小汽车

public class TopCar implements ICar{
}
public class MidCar implements ICar{
}
public class LowCar implements ICar{
}


//简单工厂:CarSimpleFactory.java

public class CarSimpleFactory{
public static final String TOPTYPE="toptype";
public static final String MIDTYPE="midtype";
public static final String LOWTYPE="lowtype";
public static ICar create(String mark){
ICar obj=null;
if(mark.equals(TOTYPE)){    //如果是高档车类型
obj=new TopCar();      //则创建高档车对象
}
if(mark.euqals(MIDTYPE)){
obj=new MidCar();
}
else if(mark.equals(LOWTYPE)){
obj=new LowCar();
}
return obj;  //返回选择的对象
}
}


//测试

public class CarTest{
public static void main(String[] args){
//从工厂中创建对象
ICar obj=CarSimpleFactory.create("toptype");
}


//代码分析

使用简单工厂的时候,没有创建简单工厂类的示例的必要。因此,可以把简单工厂类实现成一个工具类,直接使用静态方法就可以了。也就是说,简单工厂的方法通常是静态的,所以也被称为静态工厂。如果要防止客户端无谓地创造简单工厂示例,还可以把简单工厂的构造方法私有化。

//语义分析

生活中的语义分析是一个优秀的方法,可以方便构建应用程序的框架。例如甲和乙关于工厂和工作的对话,如下所示。

甲:你在哪里上班?

乙:小汽车工厂。

甲:做什么工作?

乙:生产小汽车。

甲:生产几种小汽车?

乙:高、中、低档3中小汽车。

可以看出生活中语义描述事物的一个显著特点:范围从大到小,从泛泛到具体、从一般到特殊。因此计算机程序结构一定也要遵循这种结构,即按层次划分。

抽象工厂模式



问:能否不修改工厂类就能新增一个超高档类型的汽车?

答:可以把工厂类设计为抽象类,再设计高中低档类型的子工厂类去继承它,由这些子工厂类去创建各自对应的高中低档类型汽车对象。如下:

//定义小汽车接口

public interface ICar{

}

//下面定义高、中、低档具体的小汽车

public class TopCar implements ICar{

}

public class MidCar implements ICar{

}

public class LowCar implements ICar{

}

//定义抽象工厂

public  abstract  class  AbstractFactory {
public abstract  ICar  create();  //抽象的创建方法
}


//下面定义高、中、低档具体的小汽车工厂

public class TopFactory  extends  AbstractFactory{ //子工厂继承抽象工厂
public  ICar  create(){return TopCar();}   //高档工厂生成高档小汽车对象
}
……


//测试类

public class CarTest{
public  static  void main(String[]  args){
AbstractFactory obj=new TopFactory(); //多态创建高档工厂
ICar  car = obj.create();  //获得高档工厂中创建的高档小汽车对象
}
}


接口类与抽象类的区别

抽象类里面一定有抽象方法,可能有非抽象方法,

但接口里只能有抽象方法。

声明方法的存在而不去实现它的类被叫做抽像类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。不能创建abstract 类的实例。然而可以创建一个变量,其类型是一个抽像类,并让它指向具体子类的一个实例。不能有抽像构造函数或抽像静态方法。Abstract 类的子类为它们父类中的所有抽像方法提供实现,否则它们也是抽像类为。取而代之,在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法。

接口(interface)是抽像类的变体。在接口中,所有方法都是抽像的。多继承性可通过实现这样的接口而获得。接口中的所有方法都是抽像的,没有一个有程序体。接口只可以定义static final成员变量。接口的实现与子类相似,除了该实现类不能从接口定义中继承行为。当类实现特殊接口时,它定义(即将程序体给予)所有这种接口的方法。然后,它可以在实现了该接口的类的任何对像上调用接口的方法。由于有抽像类,它允许使用接口名作为引用变量的类型。通常的动态联编将生效。引用可以转换到接口类型或从接口类型转换,instanceof 运算符可以用来决定某对象的类是否实现了接口。

抽象为什么必须是静态的:由于接口不能实例化,而非静态成员变量只能通过实例调用,静态成员变量可以通过接口调用。

为什么抽象类也不能被实例化,但抽象类里面可以定义非静态变量:

由于子类与抽象类的关系中,子类继承(extends)抽象类,

java中,子类继承父类,子类实例化,首先要执行父类的构造器,所以抽象类里面有构造器,有构造器就有实例化,

只是这种实例化是比较特殊的实例化,也不能通过new创建实例,但是可以通过该特殊的实例化调用该抽象类里面的非静态字段,通过下面的代码可以发现

public abstract class D {
//可以被子类访问
protected int d2 = 1;
//获得抽象类D的实例
public D getInstance(){
//可以使用this调用非静态成员属性,说明有实例化过程,此处输出1
System.out.println(this.d2);
return this;
}
}

public class E extends D{
//子类重写父类属性,不会发生多态
private int d2 = 2;
public static void main(String[] args) {
E e = new E();
//**java中的多态只发生在父类引用指向子类对象、子类重写父类的方法的情况下;**
//如果同样是父类引用指向子类对象、子类重写父类的属性,则不会发生多态,调用的属性还是父类的属性
System.out.println(e.getInstance().d2);//输出1,返回的是父类D的实例,
}
}


子类与接口之间的关系式implements实现,子类实现接口,无需先执行接口的构造器,

所以接口中无需提供构造器(也没有语句块),也就没有实例化的过程,对于声明一个需要通过实例访问的非静态属性也就没有意义了。

3. 为什么要用final修饰为常量:

由于接口定义了一种协议、规范,所有子类都去实现该接口,如果将Field定义为static变量,不用final修饰,

所有实现类共享该Field,一个实现类修改该变量,所有实现类都将发生改变,所以必须用final修饰

4. 为什么使用抽象类:

抽象类为子类提炼出公共的方法,并提供一个或几个抽象方法留给子类实现;

抽象类的设计体现了模板模式的设计思想,即抽象类公共的普通方法依赖一个抽象方法,而抽象方法则推迟到子类中实现细节。

5. 既然抽象类中既可以定义抽象方法,也可以定义普通方法,那为什么使用接口,而接口中只能定义抽象方法:

接口定义的一种协议、规范,体现的是规范也实现分离的松耦合的设计思想;

同时使用接口是implements实现,子类可以实现多个接口,却只能继承一个父类(java中的单继承机制);

所以子类继承一个完全是抽象方法的抽象类导致不能再继承其它类就没有什么意义了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: