今天我们来看物件导向程序设计的六个原则~
原则可以把它视为是写程序的一种好习惯~
那我们来看看这六个好习惯分别是什麽呢?
学习目标: 物件导向六个原则的概念
学习难度: ☆☆☆
第一个是 单一职责 (Single Reponsibility Principle)
单一职责原则 故名思义就是一个类别只负责一个职责~
也就是说~ 我们要让一个类别指做一个行为~
进而让程序形成高内聚、低耦合的状态!
public class GameProgrammer //游戏工程师使用游戏引擎
{
public void coding()
{
Console.WriteLine("I could used Unity to develop game");
}
}
第二个是开闭原则(Open Closed Principle)
开闭原则是指 当我们完成一个模组(类别、方法)时,就不要在对他进行修改。
也就是说,我们在设计程序时,要尽量用扩充的方式来新增功能,而要避免用修改程序的方式。
public interface IProgrammer //工程师会写Code
{
public Name{get;set;}
void coding();
}
public class GameProgrammer : IProgrammer //新增一个游戏工程师
{
public Name{get;set;}
public void coding()
{
Console.WriteLine("I could used Unity to develop game");
}
}
public class DataBaseProgrammer : IProgrammer //新增一个资料库工程师
{
public Name{get;set;}
public void coding()
{
Console.WriteLine("I could used SQL to Maintain player's data");
}
}
第三个是依赖反转原则(Dependency-Inversion Principle)
依赖反转原则 是指高阶模组(类别、方法)不应依赖低阶模组(类别、方法)~它们都应该依赖抽象。
另外~ 抽象不应该依赖於模组(类别、方法),模组(类别、方法)应该依赖抽象。
简单来说~ 我们在设计程序时~ 要将架构设计在抽象~ 在让模组去继承抽象~
public interface IProgrammer
{
public Name{get;set;}
void coding();
void debug();
}
public class GameProgrammer : IProgrammer
{
public Name{get;set;}
public void coding()
{
Console.WriteLine("I could used Unity to develop game");
}
public void debug()
{
Console.WriteLine("I could debug unity program");
}
}
public class Programmer
{
private IProgrammer iprogrammer;
public Programmer(IProgrammer programmer)
{
iprogrammer = programmer;
}
public void coding()
{
iprogrammer.coding();
}
public void debug()
{
iprogrammer.debug();
}
}
class MainProgram
{
static void Main()
{
IProgrammer i_gameProgrammer = new GameProgrammer();
Programmer gameprogrammer = new Programmer(i_gameProgrammer);
gameprogrammer.coding();
gameprogrammer.debug();
}
}
第四个是里氏替换原则(Liskov Substitution Principle)
里氏替换原则是指子类别必须能够替换父类别~
同时子类别替换父类别後,不需要改变,也不会发生任何错误或异常。
最简单来说~ 父类别能做到的事情,子类别也要能做到~
public abstract class Programmer
{
public abstract void coding();
}
public class GameProgrammer : Programmer
{
public override void coding()
{
Console.WriteLine("I could used Unity to develop game");
}
}
public class DataBaseProgrammer : Programmer
{
public override void coding()
{
Console.WriteLine("I could used SQL to maintain data");
}
}
class MainProgram
{
static void Main()
{
//因为父子类能替换,所以它们能这样实例化
Programmer gameprogrammer = new GameProgrammer();
gameprogrammer.coding();
//因为父子类能替换,所以它们能这样实例化
Programmer databaseprogrammer = new DataBaseProgrammer();
databaseprogrammer.coding();
}
}
第五个是介面隔离原则(Interface Segregation Principle)
介面隔离原则的概念很简单~ 就很像是单一职责的介面版本~
我们不应该在介面放入许多不同的抽象方法~ 因为有些子类别可能会难以实作~
例如~ 我们在工程师的介面放入弹钢琴~ 但有些工程师可能不会弹钢琴~
因此~ 那些工程师的类别就难以实现弹钢琴的抽象方法~
所以~我们应该设计许多的介面~ 然後每个介面有它专精的抽象方法~
public interface IProgrammer
{
void coding();
}
public interface IPianoPlayer
{
void playpiano();
}
public class GameProgrammer : IProgrammer, IPianoPlayer
{
public void coding()
{
Console.WriteLine("I could used Unity to develop game");
}
public void playpiano()
{
Console.WriteLine("I could played piano");
}
}
第六个是最少知识原则(Least Knowledge Principle)
最少知识原则是指一个类别只和它相关的类别依赖~
因此~最少知识原则也要求~ 一个类别应对依赖的物件有最少的了解~
我们这次都用类别来举例~
public class Customer
{
public Product product { get; set; }
public Customer()
{
product = new Product();
}
public void Access()
{
product.factory.FactorySecret(); //尽量不要让顾客读到与它无关的资料~
}
}
public class Product
{
public Factory factory { get; set; }
public Product()
{
factory = new Factory();
}
}
public class Factory
{
public void FactorySecret()
{
Console.WriteLine("This is a factory secret...");
}
}
class MainProgram
{
static void Main()
{
Customer customer = new Customer();
customer.Access(); //顾客能读到公司的秘密,很怪吧~
}
}
参考资料:
https://dotnettutorials.net/lesson/single-responsibility-principle/
https://www.c-sharpcorner.com/UploadFile/pranayamr/open-close-principle/
https://www.youtube.com/watch?v=CxsZFL6rj5c&ab_channel=anitakumari
https://dotnettutorials.net/lesson/liskov-substitution-principle/
https://dotnettutorials.net/lesson/interface-segregation-principle/
https://www.c-sharpcorner.com/article/the-law-of-demeter/
<<: 搞懂 P2P 技术 (3) - WebRTC x AWS x KVS
Spring Security 是Spring 官方建议的验证框架,提供了安全性方面的解决方案,这个...
[Day2] CSS + JS Clock 运用 CSS 和 Javascript 做一个虚拟时钟 ...
有些针对 @vue/cli 的全局配置,例如你惯用的包管理器和你本地保存的 preset,都保存在 ...
我们先来用insertion sort algorithm来解题。 虽然他的效率也不高,但这是很好理...
前言 前一篇我们介绍了如何在 Go 中对 MySQL 做操作,而 MySQL 为关联式资料库,而今天...