Java设计模式
Java的设计模式有三种类型,分别是:创建型,结构型,行为型。制定Java的设计模式有什么作用呢,有效的进行代码的编写,提高代码的可读性。
单例模式:单例模式只能创建一个实例对象,适用于只有一个实例化对象的类型,例如:工具类,线程池,缓存等等。
饿汉模式:
public class Singleton {
/**
* 单例模式:保证应用程序且只有一个实例
* 类型:饿汉模式,懒汉模式
* 饿汉模式:类进行加载是唯一类属性进行创建
*/
private static Singleton instance=new Singleton(); //创建类的唯一实例
// 封装构造方法
private Singleton(){
}
//创建类方法
public static Singleton getInstance(){
return instance;
}
public void print(){
System.out.println("hello world");
}
}
懒汉模式:
public class Singleton2 {
/**
* 懒汉模式:类方法被调用时进行类的实例化
* 区别:类加载时饿汉模式比较慢,创建对象是较快,属于线程安全,懒汉模式则相反。
*/
private Singleton2(){
}
private static Singleton2 instance;//声明类的唯一实例
public static Singleton2 getInstance(){
if (instance==null) {
instance=new Singleton2();
}
return instance;
}
public void print(){
System.out.println("hello world");
}
}
测试类:
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Singleton s1=Singleton.getInstance();
Singleton s2=Singleton.getInstance();
//测试person1和person2是否是同一个实例
if(s1==s2){
System.out.println("s1和s2是同一个实例");
}else{
System.out.println("s1和s2不是同一个实例");
}
s1.print();
Singleton2 s3=Singleton2.getInstance();
Singleton2 s4=Singleton2.getInstance();
if (s3==s4) {
System.out.println("s3和s4是同一个实例");
}else {
System.out.println("s3和s4不是同一个实例");
}
s3.print();
}
}
输出:
s1和s2是同一个实例
hello world
s3和s4是同一个实例
hello world
工厂模式:新建工厂类来管理各种类,方便程序的修改和维护。
simplefactory:简单工厂模式,通过创建一个工厂类来管理各个子类。
简单工厂的缺点:每增加一个子类,需要修改工厂类。
interface Fruit {
public void eat();
}
public class Apple implements Fruit {
@Override
public void eat() {
System.out.println("喜欢吃苹果");
}
}
public class Banana implements Fruit {
@Override
public void eat() {
System.out.println("喜欢吃香蕉");
}
}
public class Factory {
public static Fruit getFruit(String className){
if ("apple".equals(className)) {
return new Apple();
}
else if ("banana".equals(className)) {
return new Banana();
}
return null;
}
}
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
Fruit f=null;
f=Factory.getFruit("apple");
if (f!=null) {
f.eat();
}
}
}
利用反射来动态的加载类,修改工厂类:
public class Factory {
public static Fruit getFruit(String className){
Fruit fruit=null;
Class<?> class1=null;
try {
class1=Class.forName(className);
fruit=(Fruit) class1.newInstance();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return fruit; //增加子类,工厂类也不必进行修改
}
}
测试类:
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
Fruit fruit=null;
fruit=Factory.getFruit("com.qq.design.Apple");//输入完整的包.类名称
if (fruit!=null) {
fruit.eat();
}
}
}
然后发现输入完整的包类名称太过麻烦,可以设置属性文件properties配置子类的信息,属性文件中的内容以键值对的形式进行存储,通过映射则可以得到子类的完整包类名。
属性操作类:
public class PropertiesReader {
public static Properties getPro(){
Properties properties=new Properties();
File file=new File("fruit.properties");
try {
if (file.exists()) {
properties.load(new FileInputStream(file));
}else {
properties.setProperty("apple","com.qiuze.factoryMethod.Apple" );
properties.setProperty("banana","com.qiuze.factoryMethod.Banana" );
properties.store(new FileOutputStream(file),null);
}
} catch (Exception e) {
e.printStackTrace();
}
return properties;
}
}
测试类:
public class Test {
/**classname名称太长,利用属性文件键值对的映射解决
* @param args
*/
public static void main(String[] args) {
Properties pro=PropertiesReader.getPro();
Fruit fruit=null;
fruit=Factory.getFruit(pro.getProperty("banana"));
if (fruit!=null) {
fruit.eat();
}
}
}