設計原則一:把會變化的部分取出并“封裝”起來,好讓其他部分不受影響。
設計原則二:針對接口程式設計而不是針對實作程式設計。
針對實作程式設計就必須進行具體實作,針對接口程式設計,就可以對接口進行多态的調用
實作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;
}
}
複制