1.接口引用指向对象
接口引用指向对象(这是一个常用的用法)类似List list = new ArrayList()。(在以下代码
中的GlobalFactory的main()函数中)
应用背景:
(1) list 引用基本不会调用ArrayList 专有方法(当然他也调用不到),而是只调用List 接口提供的方法,
这样如果后来觉得LinkedList 可能性能更好的时候,直接把ArrayList 替换成LinkedList 即可,多方便。
(2) 如果以后要用list 要调用ArrayList 的自定义非继承List 的方法,那么这句话必须是
ArrayList list = new ArrayList()
2.工厂模式
工厂模式 : 工厂干嘛的?生产对象的。所有的工厂模式,都是用来生产对象的。
(2) 静态工厂方法:直接调用某一个类的静态方法就可以返回Bean 的实例(了解一下就够了)
接口引用指向对象(这是一个常用的用法)类似List list = new ArrayList()。(在以下代码
中的GlobalFactory的main()函数中)
应用背景:
(1) list 引用基本不会调用ArrayList 专有方法(当然他也调用不到),而是只调用List 接口提供的方法,
这样如果后来觉得LinkedList 可能性能更好的时候,直接把ArrayList 替换成LinkedList 即可,多方便。
(2) 如果以后要用list 要调用ArrayList 的自定义非继承List 的方法,那么这句话必须是
ArrayList list = new ArrayList()
2.工厂模式
工厂模式 : 工厂干嘛的?生产对象的。所有的工厂模式,都是用来生产对象的。
(1)简单工厂(了解一下就够了)
class TankFactory{
public static Tank createTank(int x,int y,boolean good,int direct){
return new Tank(); //坦克的"个性化参数"
}
}
以后调用TankFactory.createTank() 即可创建Tank 对象。可以创建n多个对象。
(2) 静态工厂方法:直接调用某一个类的静态方法就可以返回Bean 的实例(了解一下就够了)
调用方法为:PropertyMgr.getInstance( )
class PropertyMgr {
PropertyMgr propertyMgr = null;
private PropertyMgr(){
}
public static PropertyMgr getInstance( ){
if( propertyMgr == null )
propertyMgr = new PropertyMgr( );
return propertyMgr ;
}
}
这个一看就是单例。以后调用PropertyMgr.getInstance() 即可创建propertyMgr 对象。仅有一个对象存在。
(3)抽象工厂(用的很多,要掌握,实际中应用最多的就是软件换皮肤,QQ,用的是工厂模式,是最方便的,只要做好新的皮肤,换一个工厂,配置文件一改),
抽象工厂往往生产的是一套产品(下面的对象是)
//抽象工厂接口
public interface GameFactory {
public Tank createTank();
public Missile createMissile();
public Explode createExplode();
public Wall createWall();
}
//圆形坦克
public class OvalFactory implements GameFactory {
int i =0;
@Override
public Tank createTank() {System.out.println("OvalFactory createTank"); return null;}
@Override
public Missile createMissile() {return null;}
@Override
public Explode createExplode() {return null;}
@Override
public Wall createWall() {return null;}
public void onlyOvalFactory(){}
}
//方型坦克
public class RectFactory implements GameFactory {
@Override
public Tank createTank() {return null;}
@Override
public Missile createMissile() {return null;}
@Override
public Explode createExplode() {return null;}
@Override
public Wall createWall() {return null;}
}
public class GlobalFactory {
public static GameFactory gf = null;
public static String ClassName = "test.java.AbstractFactoryPattern.OvalFactory"; //这里是读配置的类名,OvalFactory / // RectFactory
public static GameFactory newInstance(){
if(gf==null){
Class cs = null;
try {
cs = Class.forName(ClassName);
gf = (GameFactory)cs.newInstance(); //反射1:new 一个对象,但是只能用Object 接收
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
}
return gf;
}
public static void main(String[] args) {//这个是测试代码,平时调用工厂创建对象在下面的类里面
GameFactory gf = GlobalFactory.newInstance(); //接口引用指向对象(这是一个常用的用法,上面有说明)
gf.createTank();//输出 OvalFactory createTank,调用的是 OvalFactory 的函数
}
}
//Tank 使用方,调用上面的抽象工厂创建Tank
public class TankClient {
public void generateScene(){
//1. low 写法
//这就是创建圆形坦克,接下来的所有gf 的都是圆形坦克的操作。以后我要创建方型坦克,直接改这里,new RectFactory(),下面所有都 //不用变。
GameFactory gf = new OvalFactory();//new 的是不同的factory,产生的就是相对应的不同的产品,此时我下面产生的子弹也是圆的 //子弹。什么都是圆的。
//如果我这里new 方型的工厂,那么下面我创建的就是方型的坦克,子弹,方型的墙。也就是我只要变着一个地方,我整个坦克,子弹墙都变, //整个界面一套全都变过来。
//这个带来的好处巨大。
Tank myTank = gf.createTank(); // 我接下来的创建tank,我不new 了,我是让工厂去产生坦克
//接下来我new 墙,new Missile,new Explode 的时候,我不是直接new 了,我是调用gf 的 crete* 方法。
//2. 单例 + 抽象工厂写法
GameFactory gf1 = GlobalFactory.newInstance(); //这样调用方TankClient 无论需要方型 / 圆形坦克,都不需要改自己代码,
//只需GlobalFactory 里面的ClassName 改变成相应类名即可(读配置文件反射方式new对象),就能切换圆形坦克还是方型坦克,
//但是上面的第一种方式,new 后面的对象名还要改
Tank myTank1 = gf1.createTank();
}
}