---------------------- ASP.Net+Android+IO开发S、.Net培训、期待与您交流! ----------------------
设计模式种类较多,这里我只记录下学习过程中的几种设计模式,它们分别为单例,装饰,模板方法,享元,工厂设计模式,其它模式有待学习。
1、 单例设计模式
目的:希望对象只创建一个实例,那么需保证一个类在内存中的对象唯一。
比如:多个程序读取一个配置文件,那么将配置文件封装成对象,这样会方便文件中的数据操作,为了数据的正确性,又得保证多个程序读到的是同一个配置文件对象,那么这时配置文件对象需在内存中唯一,采用单例模式。
如何实现:
(1)私有化构造函数
(2)创建私用且是静态的本类对象。
(3)定义公有且静态的方法,返回本类对象。
两种实现方式:饿汉式和懒汉式。两者区别就是本类对象的创建时间,懒汉式将本类对象的初始化放进了返回本类对象的方法中,延迟了本类对象的初始,在不确定是否使用对象时,懒汉式倒是可以节约内存。下面看具体代码理解:
//饿汉式
class Single{
private Single(){};
private static final Single instance = new Single();
public static Single getInstance (){
return instance;
}
}
//懒汉式
class Single
{
private Single(){}
private static Single instance = null;
public static Single getInstance()
{
if(instance==null){
//防止多线程下的同步问题
synchronized(Single.class)
{
if(instance == null){
instance = new Single();
}
}
}
return instance;
}
}
一般实际开发中都是使用饿汉式,懒汉式在多线程下会出现同步问题,上述懒汉式代码加了同步锁,并以双重判断提高效率,不过也是由于这些处理,在效率上还是低于饿汉式。
2、 装饰设计模式
装饰设计模式要做的是动态的给一个对象添加一些额外的职责。相对于派生子类去扩展功能,装饰模式扩展更灵活。
若一个父类有子类,子类要增强功能,考虑封装性,我们为子类再增加一个子类用来增强功能的,那么有这么一种情况,父类每增加一个子类,子类又得附带一个子类,结果子类过多膨胀,这时考虑装饰模式。定义一个专门的装饰类,哪个子类要增强功能,就用该装饰类包装。
像IO流的输入输出缓冲方式,采用了装饰模式。
适用性:
(1) 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
(2) 处理那些可以撤销的职责。
(3) 当不能采用生成子类的方法进行扩充时。
看示例,有多个子类,只需一个装饰类就可:
interface iReader{
public void read();
}
//子类1
class ReadJpg implements iReader{
@Override
public void read(){
System.out.println("一点点读");
}
}
//子类2,或者有多个
class ReadTxt implements iReader{
@Override
public void read(){
System.out.println("一点点读");
}
}
//只要一个装饰类,增加缓冲区功能,先快速读到缓冲区,再一行行从缓冲区读
class ReadBuffer implements iReader
{
private iReader rd;
public ReadBuffer(iReader rd){
this.rd = rd;
}
@Override
public void read()
{
rd.read();
System.out.println("读到缓冲区,再从缓冲区一行行读");
}
}
public class DecoratorDesign
{
public static void main(String[] args)
{
ReadTxt rt = new ReadTxt();
ReadBuffer buf = new ReadBuffer(rt);
buf.read();
}
}
3、 模板方法设计模式
即固定可重复使用的部分写成模板,这里加个final写成模板方法,将不确定的部分抽取出来抛给外部(这里是子类)去定义。
比较简单直接看示例代码:
abstract class Template{
public abstract void print();
public final long printTime(){
long time = System.currentTimeMillis();
print();//变化的部分,其余不变
time = System.currentTimeMillis() -time;
return time;
}
}
public class TemplateDesign
{
public static void main(String[] args)
{
//time = 匿名内部类(匿名子类对象).printTime();
long time = new Template(){
//复写print()
@Override
public void print(){
System.out.println("打印1本书....");
System.out.println("打印2本书....");
}
}.printTime();
System.out.println(time);
}
}
4、 享元设计模式
享元模式,即多个使用者共享某一个对象,当然这个对象是具备使用者的共性需求,如有多个使用者,一人有一个对象,但这些对象其实都是些共性方法,为了节约资源,使用者共享一个即可。
来个示例,如要把一串大写字符串转小写,如AAAAAAABBBBC,那么你只需要abc三个小写字母就可以了,每一个大写字母A转换小写a,都是共享了一个a。同理只要26个小写字母,你能转换任意长的大写字母串。
我们将字母当作一个个对象处理,看具体代码:
import java.util.HashMap; import java.util.Map; //接口,给对象增加行为 interface iFlyweight{ public abstract void action(); } //实现 class FlyweightImpl implements iFlyweight{ private String ch; public FlyweightImpl(String ch){ this.ch = ch; } //字母转换行为 @Override public void action(){ System.out.println(ch.toLowerCase()); } } //对象工厂,生成对象的 class FlyweightFactory{ private static Map map = new HashMap(); //由ch对象为键值,FlyweightImpl对象为其对应行为 public iFlyweight getFlyweight(Stringch){ //ch对象不存在,则添加一个,存在,则直接获取 if(map.get(ch) == null){ map.put(ch, new FlyweightImpl(ch)); } return (iFlyweight)map.get(ch); } //看有多少对象 public int getSize(){ return map.size(); } } //测试类 public class FlyweightDesign { public static void main(String[] args) { FlyweightFactory factory = new FlyweightFactory(); //使用对象 iFlyweight fly1 = factory.getFlyweight("A"); fly1.action(); iFlyweight fly2 = factory.getFlyweight("B"); fly2.action(); iFlyweight fly3 = factory.getFlyweight("A"); fly3.action(); //检测是否在共享一个对象 System.out.println(fly1 == fly3); System.out.println(factory.getSize()+"对象"); } }
其实上述例子,就是一个对象去重复的例子,保证对象的唯一性即可。
5、 工厂设计模式
工厂模式用于创建对象实例的,根据传入的数据,动态的决定需要返回哪一个类的实例。
适用场景:
(1) 当一个类不知道它所创建的对象的类的时候。
(2) 当一个类希望由他的子类来指定它所创建的对象的时候。
下面看以个简单工厂的示例:
//对象接口 interface iPerson{ } //实现iPerson接口,即产品对象 class Student implements iPerson{ public Student(){ System.out.println("学生"); } } class Teacher implements iPerson{ public Teacher(){ System.out.println("老师"); } } //简单工厂 class Factory{ public iPerson getPerson(String type) { if(type.equals("student")) return new Student(); else if(type.equals("teacher")) return new Teacher(); return null; } } public class FactoryDesignDemo { public static void main(String[] args) { Factory fcy = new Factory(); iPerson student =fcy.getPerson("student"); iPerson teacher =fcy.getPerson("teacher"); } }
---------------------- ASP.Net+Android+IO开发S、.Net培训、期待与您交流! ----------------------