设计原则一:把会变化的部分取出并“封装”起来,好让其他部分不受影响。
设计原则二:针对接口编程而不是针对实现编程。
针对实现编程就必须进行具体实现,针对接口编程,就可以对接口进行多态的调用
实现Animal接口,并创建所有的空方法。
实现Dog类,Cat类,实现具体的类
Animal animal = new Dog();
Animal animal = new Cat();
animal.bark()
这就会在运行时实现相应的方法
FlyBehavior 和 QuackBehavior 是飞和叫行为的接口
针对接口实现具体的飞行和叫的类
整合
public Duck(){
QuackBehavior quackBehavior;
public void performQuack(){
quackBehavior.quack();
}
}
抽象父类只负责实现相应功能不用管具体是哪一个实现。
子类想调用哪一个行为,就new一个新的行为。
public class MallardDuck extends Duck{
public MallardDuck(){
quackBehavior = new Quack();
flyBehavior = new FlyWithWings();
}
}
public interface FlyBehavior {
void doFly();
}
public interface QuackBehavior {
void doQuack();
}
public class FlyNoWings implements FlyBehavior {
@Override
public void doFly() {
System.out.println("只能飞过墙头");
}
}
public class FlyWithWings implements FlyBehavior {
@Override
public void doFly() {
System.out.println("实现高度800米的飞翔");
}
}
public class QuackMute implements QuackBehavior {
@Override
public void doQuack() {
System.out.println("轻轻的叫");
}
}
public class SQuack implements QuackBehavior {
@Override
public void doQuack() {
System.out.println("呱呱的叫");
}
}
abstract public class Duck {
FlyBehavior flyBehavior;
QuackBehavior quackBehavior;
public void performFly(){
flyBehavior.doFly();
}
public void performQuack(){
quackBehavior.doQuack();
}
public void setFlyBehavior(FlyBehavior flyBehavior){
this.flyBehavior = flyBehavior;
}
public void setQuackBehavior(QuackBehavior quackBehavior){
this.quackBehavior = quackBehavior;
}
}
public class SmallDuck extends Duck {
}
public class Main {
public static void main(String[] args) {
SmallDuck smallDuck = new SmallDuck();
smallDuck.setFlyBehavior(new FlyNoWings());
smallDuck.setQuackBehavior(new QuackMute());
smallDuck.performFly();
smallDuck.performQuack();
}
}
观察者模式
出版者 + 订阅者 = 观察者模式
设计原则三:为了交互对象之间的松耦合而设计
/***
* 主题需要提供注册,删除,全局通知接口
*/
public interface Subject {
public void registerObserver(Observer o);
public void removeRegister(Observer o);
public void notifyObservers();
}
/***
* 观察者接口需要提供观察者接受消息更新的统一接口
*/
public interface Observer {
public void update(int temp,int humidity,int pressure);
}
/***
* 展示模块,需要提供展示的统一接口
*/
public interface DisplayElement {
public void display();
}
public class WeatherData implements Subject {
private List<Observer> observerList = null;
private int temp;
private int humidity;
private int pressure;
public WeatherData(){
observerList = new ArrayList<Observer>();
}
@Override
public void registerObserver(Observer o) {
observerList.add(o);
}
@Override
public void removeRegister(Observer o) {
int index = observerList.indexOf(o);
observerList.remove(index);
}
@Override
public void notifyObservers() {
for (Observer it: observerList) {
it.update(temp,humidity,pressure);
}
}
public void measureChanged(){
notifyObservers();
}
public void setMeasure(int temp,int humidity,int pressure){
this.temp = temp;
this.humidity = humidity;
this.pressure = pressure;
measureChanged();
}
}
public class ForecastDisplay implements Observer, DisplayElement {
private int temp;
private int pressure;
private Subject weatherData;
public ForecastDisplay(Subject weatherData){
this.weatherData = weatherData;
weatherData.registerObserver(this);
}
@Override
public void display() {
System.out.println("temp is " + temp + " pressure" + pressure + " weatherData" + weatherData);
}
@Override
public void update(int temp, int humidity, int pressure) {
this.temp = temp;
this.pressure = pressure;
display();
}
}
public class CurrentDisplay implements Observer, DisplayElement {
private int temp;
private int humidity;
private Subject weatherData;
public CurrentDisplay(Subject weatherData){
this.weatherData = weatherData;
weatherData.registerObserver(this);
}
@Override
public void display() {
System.out.println("Current conditions: " + temp + "F degrees and "+ humidity + "% humidity");
}
@Override
public void update(int temp, int humidity, int pressure) {
this.temp = temp;
this.humidity = humidity;
this.display();
}
}
public static void main(String[] args) {
WeatherData weatherData = new WeatherData();
CurrentDisplay currentDisplay = new CurrentDisplay(weatherData);
ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData);
weatherData.setMeasure(15,16,19);
}
多用组合,少用继承。
观察者模式-在对象间定义一个一对多的依赖,这样。主题用一个 共同的接口更新观察者。
Swing ,JavaBeans,RMI,大量使用观察者模式。
装饰者模式
设计原则四,类应该对扩展开放,对修改关闭。
装饰者动态的将责任附加到对象上,若要扩展功能,装饰者比继承更有弹性替代方案。
public abstract class Beverage {
String description = "Unkown Beverage";
public String getDescription(){
return description;
}
public abstract double cost();
}
public abstract class CondimentDecorator extends Beverage {
public abstract String getDescription();
}
public class DarkRoast extends CondimentDecorator {
Beverage beverage;
public DarkRoast(Beverage beverage){
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription() + ", DarkRoast";
}
@Override
public double cost() {
return beverage.cost() + 0.36;
}
}
public class Espresso extends Beverage {
public Espresso(){
description = "Espresso";
}
@Override
public double cost() {
return 1.99;
}
}
public class HouseBlend extends Beverage {
public HouseBlend(){
description = "HouseBlend";
}
@Override
public double cost() {
return 0.89;
}
}
public class Mocha extends CondimentDecorator {
Beverage beverage;
public Mocha(Beverage beverage){
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription() + ", Mocha";
}
@Override
public double cost() {
return beverage.cost() + .20;
}
}
public static void main(String[] args) {
Beverage beverage = new Espresso();
Beverage beverage1 = new HouseBlend();
Beverage sum = new Mocha(beverage);
System.out.println(sum.getDescription());
Beverage sum1 = new DarkRoast(sum);
System.out.println(sum1.getDescription() + sum1.cost());
}
java I/O中有大量装饰器的实现代码,InputStream,FileInputStream,StringBufferInputStream
装饰器是除了继承外的另一种扩展方式。
装饰器可以在被装饰者的行为面前加上自己的行为,甚至被装饰者整个行为被去掉。
工厂模式
工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个,工厂方法让类把实例化推迟到子类。
设计原则五,要依赖抽象,不要依赖具体类。
/**
* 创建接口
*/
public interface Shape {
void draw();
}
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("draw a Circle ~~");
}
}
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("draw a new Rectangle ~~~");
}
}
public class ShapeFactory {
public Shape getShape(String shapeType){
if(shapeType==null){
return null;
}
if(shapeType.equalsIgnoreCase("CIRCLE")){
return new Circle();
}else if(shapeType.equalsIgnoreCase("RECTANGLE")){
return new Rectangle();
}
return null;
}
}
public class Main {
public static void main(String[] args) {
ShapeFactory shapeFactory = new ShapeFactory();
//获取circle
Shape shape1 = shapeFactory.getShape("CIRCLE");
Shape shape2 = shapeFactory.getShape("RECTANGLE");
shape1.draw();
shape2.draw();
}
}
单例模式
有些对象我们只需要一个:线程池,缓存,对话框等等。
含有私有构造器的类不能被实例化
public class Singleton {
private static Singleton uniqueInstance;
private Singleton(){}
public static Singleton getInstance(){
if(uniqueInstance==null){
return new Singleton();
}else{
return uniqueInstance;
}
}
}
命令模式
实现命令接口,让所有命令对象实现包含相同方法的接口。
命令模式,就是将实体类的方法的执行进行封装
- 实现统一的方法执行接口,对每一个方法的执行实现一个类的封装
- 实现 对Command的传入,执行
class Light{
public void on {
print("light is on")
}
public void off {
print("light is off")
}
}
public interface Command {
public void execute();
}
public class LightOnCommand implements Command{
Light light;
public LightOnCommand(Light light){
this.light = light
}
public void execute(){
light.on()
}
}
实现接口的传入,与执行这样和底层进行分开,实现的单独的命令执行
public class SimpleRemoteControl{
Command solt;
public SimpleRemoteControl(){}
public void setCommand(Command command){
slot = command;
}
public void buttonWasPassed(){
slot.execute();
}
}
适配器模型
适配器,相当于两个类的对接接口
A 强转 B 适配器的实现是创建一个类,实现B接口,同时通过构造函数传参A,在实现的B的方法中执行A方法。
B接口与实现类
public interface Duck{
public void quick();
public void fly();
}
public class MallarDuck implements Duck{
public void quick(){
print("Quick")
}
public void fly(){
print("fly")
}
}
A接口与实现类
public interface Turkey{
public void gobble();
public void fly();
}
public class WildTurkey implements Turkey{
public void gobble(){
print("GOOBLE")
}
public void fly(){
print("Fly")
}
}
适配器
public TurkeyAdapter implements Duck{
Turkey turkey;
public TurkeyAdapter(Turkey turkey){
this.turkey = turkey;
}
public void quack(){
turkey.gobble();
}
public void fly(){
turkey.fly()
}
}
模板模式
模板方法把一类的操作给单独抽出来
public abstract class CaffeineBeverageWithHook {
//提出公共的方法流程
void prepareRecipe(){
boilWater();
brew();
pourInCup();
if(customerWantsCondiments()){
addCondiments();
}
}
//不同饮料,最大的不同点,可以抽象化
abstract void brew();
abstract void addCondiments();
void boilWater(){
System.out.println("boiling water");
}
void pourInCup(){
System.out.println("pouring into cup");
}
boolean customerWantsCondiments(){
return true;
}
}
public class CoffeeWithHook extends CaffeineBeverageWithHook {
@Override
void brew() {
System.out.println("Dripping Coffee through filter");
}
@Override
void addCondiments() {
System.out.println("Adding Suger and Milk");
}
public boolean customerWantsCondiments(){
String answer = getUserInput();
if(answer.startsWith("y")){
return true;
}else{
return false;
}
}
private String getUserInput(){
String answer = null;
System.out.println("Would you like milk and sugar with your coffee (y/n)");
return answer;
}
}
迭代器模式
public interface Iterator{
boolean hasNext();
Object next();
}
public class MenuItem {
String name;
String description;
boolean vegetarian;
double price;
public MenuItem(String name,String description,boolean vegetarian,double price){
this.name = name;
this.description = description;
this.vegetarian = vegetarian;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public boolean isVegetarian() {
return vegetarian;
}
public void setVegetarian(boolean vegetarian) {
this.vegetarian = vegetarian;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}
/**
* 针对接口编程,对于每一个数组或者集合实现Iterator ,这样对于数组和列表的遍历
* 在程序底层只用实现对Iterator的遍历
*/
public class DinerMenuIterator implements Iterator {
MenuItem[] items;
int position = 0;
public DinerMenuIterator(MenuItem[] items){
this.items = items;
}
@Override
public boolean hasNext() {
if(position>=items.length || items[position] == null){
return false;
}else {
return true;
}
}
@Override
public Object next() {
MenuItem menuItem = items[position];
position = position + 1;
return menuItem;
}
}
public class PanCakeMenuIterator implements Iterator {
ArrayList<MenuItem> items;
int position = 0;
public PanCakeMenuIterator(ArrayList<MenuItem> items){
this.items = items;
}
@Override
public boolean hasNext() {
if(position == items.size() || items.get(position) ==null){
return false;
}else {
return true;
}
}
@Override
public Object next() {
MenuItem item = items.get(position);
position = position + 1;
return item;
}
}
网友评论