继承的好处:让共同部分,可以复用.避免重复编程.
继承的不好:耦合性高.一旦超类添加一个新方法,子类都继承,拥有此方法,若子类相当部分不实现此方法,则要进行大批量修改.
继承时,子类就不可继承其它类了.
接口的好处:解决了继承耦合性高的问题.且可让实现类,继承或实现其它类或接口.
接口的不好:不能真正实现代码的复用.
我们设计的原则是:找出应用中相同之处,且不容易发生变化的东西,把它们抽取到抽象类中,让子类去继承它们;
找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。
参考:java常用设计模式
static Factory Method(工厂模式):
参考:java工厂模式
在设计模式中,Factory Method也是比较简单的一个,但应用非常广泛,EJB,RMI,COM,CORBA,Swing中都可以看到此模式
的影子,它是最重要的模式之一.在很多地方我们都会看到xxxFactory这样命名的类.
工厂模式按照《Java与模式》中的提法分为三类:
1. 简单工厂模式(Simple Factory)
2. 工厂方法模式(Factory Method)
3. 抽象工厂模式(Abstract Factory)
这三种模式从上到下逐步抽象,并且更具一般性。
还有一种分类法,就是将简单工厂模式看为工厂方法模式的一种特例,两个归为一类。两者皆可,这本为使用《Java与模式》的分类方法。
在什么样的情况下我们应该记得使用工厂模式呢?大体有两点:
1.在编码时不能预见需要创建哪种类的实例。
2.系统不应依赖于产品类实例如何被创建、组合和表达的细节
工厂模式能给我们的OOD、OOP带来哪些好处呢??
等我们讲完后,大概你就能知道了
那么简单工厂模式怎么用呢?我来举个例子吧,我想这个比讲一大段理论上的文字描述要容易理解的多!下面就来给那个暴发户治病 : P
在使用了简单工厂模式后,现在暴发户只需要坐在车里对司机说句:"开车"就可以了。来看看怎么实现的:
//抽象产品角色
public interface Car{
public void drive();
}
//具体产品角色
public class Benz implements Car{
public void drive() {
System.out.println("Driving Benz ");
}
}
public class Bmw implements Car{
public void drive() {
System.out.println("Driving Bmw ");
}
}
。。。(奥迪我就不写了:P)
//工厂类角色
public class Driver{
//工厂方法
//注意 返回类型为抽象产品角色
public static Car driverCar(String s)throws Exception {
//判断逻辑,返回具体的产品角色给Client
if(s.equalsIgnoreCase("Benz")) return new Benz();
else if(s.equalsIgnoreCase("Bmw"))
return new Bmw();
......
else throw new Exception();
。。。
//欢迎暴发户出场......
public class Magnate{
public static void main(String[] args){
try{
//告诉司机我今天坐奔驰
Car car = Driver.driverCar("benz");
//下命令:开车
car.drive();
。。。
singelton(单例模式)
Singleton 是一种创建性模型,它用来确保只产生一个实例,并提供一个访问它的全局访问点.对一些类来说,保证只有一个实例是很重要的,比如有的时候,数据库连接或 Socket 连接要受到一定的限制,必须保持同一时间只能有一个连接的存在.
运用:
在于使用static变量;
构造方法私有化
public class Singleton {
private static Singleton singleton; // 构造方法私有化,保证在类的外部无法实例化该类的对象
private Singleton() {
}
public static synchronized Singleton getSingletonInstance() {
if (singleton == null) {
singleton = new Singleton();
}
return singleton;
}
}
观察者模式(Observer)
(1)
基本概念:
观察者模式属于行为型模式,其意图是定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
这一个模式的关键对象是目标(Subject)和观察者(Observer)。一个目标可以有任意数目的依赖它的观察者,一旦目标的状态发生改变,所有的观察者都得到通知,作为对这个通知的响应,每个观察者都将查询目标以使其状态与目标的状态同步。
适用场景:
观察者模式,用于存在一对多依赖关系的对象间,当被依赖者变化时,通知依赖者全部进行更新。因此,被依赖者,应该有添加/删除依赖者的方法,且可以将添加的依赖者放到一个容器中;且有一个方法去通知依赖者进行更新。
(2)
思想:
(一)
建立目标(subject)与观察者(observer)接口:
目标(subject)接口:
建立一个注册观察者对象的接口; public void attach(Observer o);
建立一个删除观察者对象的接口; public void detach(Observer o);
建立一个当目标状态发生改变时,发布通知给观察者对象的接口; public void notice();
观察者(observer)接口:
建立一个当收到目标通知后的更新接口: public void update();
外观模式(Facade)
(1)
外观模式属于结构型模式,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
外观模式的主要用途就是为子系统的复杂处理过程提供方便的调用方法,使得子系统更加容易被使用。
-->将复杂的过程包含在里面,提供一个简单的应用接口即可.
(2)
例如在一个泡茶的过程中,需要作如下的工作:烧开水,准备茶叶,把茶叶放在被子里,把烧开的水放到茶杯中,只
有经过这些过程之后才能泡出好的茶叶来。这是一个常用的步骤,80%的泡茶步骤都是这个样子的,可以把这些动作串
联起来,形成一个整体的步骤.如下例的MakeACuppa(),使用了facade的模式,这样在调用步方法时就比较方便。这便
是外观模式,里面的细节被屏蔽掉了。
模板模式(Template):
RefreshBeverage.java:
/**
* 抽象基类,为所有子类提供一个算法框架
*
* 提神饮料
*
* @author jacky 2014年12月28日
*/
public abstract class RefreshBeverage {
/**
* 制备饮料的的模板方法 封装所有子类共同遵循的算法框架
* final表示子类不能覆写,即表示子类不能改变算法框架
*/
public final void prepraeBeverageTemplate() {
// 1.将水煮沸
boilWater();
// 2.泡制饮料
brew();
// 3.将饮料倒入杯中
pourIncup();
if(isCustomerWantsCondiments()){
// 4.加入调味品
addCondiments();
}
//饮料泡好了
ok();
}
/**
* Hook,钩子函数(灵活性),提供一个默认或空的实现
* 询问用户是否加入调料
* @return
*/
protected boolean isCustomerWantsCondiments() {
// TODO Auto-generated method stub
return true;
}
/**
* 基本方法,将水煮沸
*/
private void boilWater() {
// TODO Auto-generated method stub
System.out.println("将水煮沸");
}
/**
* 基本方法,将饮料倒入杯中
*/
private void pourIncup() {
// TODO Auto-generated method stub
System.out.println("将饮料倒入杯中");
}
/**
* 基本方法,饮料泡好了
*/
private void ok() {
// TODO Auto-generated method stub
System.out.println("饮料泡好了");
}
/**
* 抽象基本方法,泡制饮料
*/
protected abstract void brew();
/**
* 抽象基本方法,加入调味品
*/
protected abstract void addCondiments();
}
Coffee.java:
public class Coffee extends RefreshBeverage {
@Override
protected void brew() {
// TODO Auto-generated method stub
System.out.println("用沸水冲泡咖啡");
}
@Override
protected void addCondiments() {
// TODO Auto-generated method stub
System.out.println("加入牛奶");
}
}
Tea.java:
public class Tea extends RefreshBeverage {
@Override
protected void brew() {
// TODO Auto-generated method stub
System.out.println("用沸水冲泡茶");
}
@Override
protected void addCondiments() {
// TODO Auto-generated method stub
System.out.println("加入茶叶");
}
/**
* 子类通过覆盖的形式选择挂在钩子函数
*/
@Override
protected boolean isCustomerWantsCondiments(){
return false;
}
}
TemplateTest.java:
/**
* 工厂方法使用一个抽象工厂角色作为核心来代替在简单工厂模式中使用具体类作为核心。
*
* @author jacky 2014年12月27日
*/
public class TemplateTest {
public static void main(String args[]) {
RefreshBeverage cafe = new Coffee();
cafe.prepraeBeverageTemplate();
System.out.println("--------------------------------");
RefreshBeverage tea = new Tea();
tea.prepraeBeverageTemplate();
}
}
结果:
将水煮沸
用沸水冲泡咖啡
将饮料倒入杯中
加入牛奶
饮料泡好了
--------------------------------
将水煮沸
用沸水冲泡茶
将饮料倒入杯中
饮料泡好了