1):单例模式
package designMode.singleton;
/**
* 单例模式形成的原因:
*
* 构造器私有---> 外界无法实例化,就在类内部创建一个实例对象,用static修饰,可以用类名直接调用---> 但是,类的一般用法都讲究封装,实例化对象封装
* ---> 创建getInstance()方法 ---> 由于instance是静态属性,所以方法需要static修饰
*
*/
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton(){
}
public static Singleton getInstance(){
return instance;
}
public void print(){
System.out.println("单例模式!");
}
public static void main(String[] args) {
Singleton s1 = Singleton.getInstance();//访问类中的静态方法,取得类中的静态实例
Singleton s2 = Singleton.getInstance();
Singleton s3 = Singleton.getInstance();
s1.print(); //输出信息
s2.print();
s3.print();
}
}
结果:
单例模式!
单例模式!
单例模式!
2):工厂模式:
程序在接口和子类之间加入了一个过度端,通过此过度端取得接口的实例化对象,一般都会称这个过渡端为工厂类;
因为接口对象的实例是从工厂取得的,以后如果再有子类扩充,直接修改工厂类客户端既可以根据标记得到相应的实例,灵活性较高。
package designMode.factory;
/**
* 父接口
*
*/
public interface Fruit {
void eat();
}
package designMode.factory;
public class Apple implements Fruit {
@Override
public void eat() {
System.out.println("**吃苹果");
}
}
package designMode.factory;
public class Orange implements Fruit{
@Override
public void eat() {
System.out.println("**吃橘子");
}
}
package designMode.factory;
public class Factory {
public static Fruit getInstance(String fruitString){
Fruit fruit = null;
if(fruitString.equals("apple")){
fruit = new Apple();
}
if(fruitString.equals("orange")){
fruit = new Orange();
}
return fruit;
}
}
package designMode.factory;
/**
* 工厂模式
*
*/
public class FactoryDemo {
public static void main(String[] args) {
Fruit fruit = null;
fruit = Factory.getInstance("designMode.factory.Orange ");
fruit.eat();
}
}
结果:
**吃橘子
将反射应用在工厂模式上
package designMode.factory;
/**
* 工厂模式
*
*/
public class FactoryDemo {
public static void main(String[] args) {
Fruit fruit = null;
fruit = Factory.getInstance("orange");
fruit.eat();
}
}
结果;
**吃橘子
对比:运用反射的好处,
无论增加多少个子类,子类增加多个个属性,工厂类不用做任何的修改。
3):代理模式:
用户只关心上网,代理处理如何上网,
定义一个上网接口,用户和代理都实现该接口,分别做自己要做的事情,
package designMode.proxy;
public interface Network {
void browse();
}
package designMode.proxy;
public class Real implements Network{ //真实的上网操作。
@Override
public void browse() {
System.out.println("真实的上网操作");
}
}
package designMode.proxy;
public class Proxy implements Network {
private Network network;
public Proxy(Network network){
this.network = network;
}
public void check(){
System.out.println("代理检查用户是否合法");
}
@Override
public void browse() {
check();
network.browse();
}
}
package designMode.proxy;
/**
* 代理模式
*
*/
public class ProxyDemo {
public static void main(String[] args) {
new Proxy(new Real()).browse(); //有参构造,实例化代理,执行代理的方法。
}
}
结果:
代理检查用户是否合法
真实的上网操作
4):适配器模式:
主接口有太多的方法,如果直接实现,就必须覆写全部的方法,如果我只想操作其中的几个,就需要是用适配器进行适配。
package designMode.adapter;
public interface Window {//定义接口,,定义了很多的方法,但是只需要使用其中个别的方法,就需要使用代理模式了
void open();
void close();
void activated();
void iconified();
void deiconified();
}
package designMode.adapter;
public abstract class WindowAdapter implements Window {//用抽象类实现接口,方法体为空
@Override
public void activated() {
// TODO Auto-generated method stub
}
@Override
public void close() {
// TODO Auto-generated method stub
}
@Override
public void deiconified() {
// TODO Auto-generated method stub
}
@Override
public void iconified() {
// TODO Auto-generated method stub
}
@Override
public void open() {
// TODO Auto-generated method stub
}
}
package designMode.adapter;
import java.awt.event.WindowAdapter;
public class WindowImpl extends WindowAdapter { //实例体继承 抽象类。重写需要的方法
public void open(){
System.out.println("窗口打开");
}
public void close(){
System.out.println("窗口关闭");
}
}
package designMode.adapter;
public class AdapterDemo {
public static void main(String[] args) { //调用接口父类,执行需要的方法,其他的方法没有结果,在公司的eclipse上运行成功了,可是我自己的却不行,不知道是什么原因
Window window = (Window) new WindowImpl();
window.open();
window.close();
window.activated();
System.out.println();
window.iconified();
System.out.println();
window.deiconified();
}
}
结果:
窗口打开
窗口关闭
5):观察者设计模式
什么叫做观察者
举个例子,现在很多人买房,都在关注房价,如果价格变动,所有的购房者都可以观察到,(购房者就是观察者,这就叫观察者设计模式)java中使用Observable类和Observer接口,轻松实现上述功能。
package library.watch;
import java.util.Observable;
public class House extends Observable{
private float price;
public House(float price){
this.price = price;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
super.setChanged(); //设置变化点
super.notifyObservers(price); //通知所有观察者价格改变
this.price = price;
}
@Override
public String toString() {
return "房子价格为: price=" + price;
}
}
package library.watch;
import java.util.Observable;
import java.util.Observer;
public class HousePriceObserver implements Observer {
private String name;
public HousePriceObserver(String name) {
super();
this.name = name;
}
@Override
public void update(Observable o, Object arg) {
if (arg instanceof Float) { //判断参数类型
System.out.print(this.name +"观察到价格更改为:");
System.out.println(((Float)arg).floatValue());
}
}
public static void main(String[] args) {
House h = new House(1000000);
HousePriceObserver hpo1 = new HousePriceObserver("购房者A");
HousePriceObserver hpo2 = new HousePriceObserver("购房者B");
HousePriceObserver hpo3 = new HousePriceObserver("购房者C");
h.addObserver(hpo1); //加入观察者
h.addObserver(hpo2);
h.addObserver(hpo3);
System.out.println(h); //输出房子价格
h.setPrice(600000); //修改房子价格
System.out.println(h);
}
}
结果:
房子价格为: price=1000000.0
购房者C观察到价格更改为:600000.0
购房者B观察到价格更改为:600000.0
购房者A观察到价格更改为:600000.0
房子价格为: price=600000.0
抽象类--->摸具(继承的子类都具有父类的全部特征)
接口 --->指定标准(子类需要全部执行这些标准)
JDK1.8开始,可以在接口中定义普通方法:
产生背景:如果一个接口已经产生了至少30万个子类,突然有一天需要增加接口功能,并且这些方法对于所有的子类实现都是相同的,难道要子类覆写30万次?
如此,1.8之后,放宽接口的定义要求,可以定义抽象方法和静态方法,并且这些方法可以根据子类继承的原则被所有的接口子类继承。