Давайте пока с простейшего примера, потом, возможно, добавлю чуть интереснее:
| C# |
| namespace ConsoleApp4 {
internal class Program {
class Widget {
public string? ControlName { get; set; }
public string? ControlId { get; set; }
public virtual void Render() {
Console.WriteLine(ControlName + "=" + ControlId);
}
}
class TextEditWidget : Widget {
public string? Text { get; set; }
public override void Render() {
base.Render();
Console.WriteLine("Text=" + Text);
}
}
class CheckWidget : Widget {
public bool IsChecked { get; set; }
public override void Render() {
base.Render();
Console.WriteLine("IsChecked=" + IsChecked);
}
}
static void Main(string[] args) {
List<Widget> widgets = new List<Widget>();
widgets.Add(new TextEditWidget() { ControlId = "1", ControlName="Text1", Text="text"});
widgets.Add(new CheckWidget { ControlId = "2", ControlName = "Check1", IsChecked = true});
foreach (var widget in widgets)
{
widget.Render();
}
}
}
}
|
| |
42 строки
| C++ |
| #include <iostream>
#include <string>
#include <vector>
#include <memory>
class Widget {
public:
std::string controlName;
std::string controlId;
Widget(const std::string& controlName, const std::string& controlId) noexcept
: controlName(controlName), controlId(controlId) { }
virtual void Render() {
std::cout << controlName << "=" << controlId << std::endl;
}
};
class TextEditWidget : public Widget {
public:
std::string text;
TextEditWidget(const std::string& controlName, const std::string& controlId, const std::string& text) noexcept
: Widget(controlName, controlId), text(text) { }
void Render() override {
Widget::Render();
std::cout << "Text=" << text << std::endl;
}
};
class CheckWidget : public Widget {
public:
bool isChecked;
CheckWidget(const std::string& controlName, const std::string& controlId, const bool isChecked) noexcept
: Widget(controlName, controlId), isChecked(isChecked) { }
void Render() override {
Widget::Render();
std::cout << "IsChecked=" << isChecked << std::endl;
}
};
int main() {
std::vector<std::unique_ptr<Widget>> widgets;
auto textWidget = std::make_unique<TextEditWidget>("1", "Text1", "text");
widgets.push_back(std::move(textWidget));
auto checkWidget = std::make_unique<CheckWidget>("2", "Check1", true);
widgets.push_back(std::move(checkWidget));
for (const auto& widget : widgets) {
widget->Render();
}
return 0;
}
|
| |
59 строк
| Rust |
| trait Widget {
fn render(&self);
}
struct BaseWidget {
control_name: Option<String>,
control_id: Option<String>,
}
impl Widget for BaseWidget {
fn render(&self) {
if let Some(ref name) = self.control_name {
print!("{}", name);
}
print!("=");
if let Some(ref id) = self.control_id {
print!("{}", id);
}
println!();
}
}
struct TextEditWidget {
base: BaseWidget,
text: Option<String>,
}
impl Widget for TextEditWidget {
fn render(&self) {
self.base.render();
if let Some(ref text) = self.text {
println!("Text={}", text);
}
}
}
struct CheckWidget {
base: BaseWidget,
is_checked: bool,
}
impl Widget for CheckWidget {
fn render(&self) {
self.base.render();
println!("IsChecked={}", self.is_checked);
}
}
fn main() {
let widgets: Vec<Box<dyn Widget>> = vec![
Box::new(TextEditWidget {
base: BaseWidget {
control_id: Some("1".to_string()),
control_name: Some("Text1".to_string()),
},
text: Some("text".to_string()),
}),
Box::new(CheckWidget {
base: BaseWidget {
control_id: Some("2".to_string()),
control_name: Some("Check1".to_string()),
},
is_checked: true,
}),
];
for widget in widgets {
widget.render();
}
}
|
| |
73 строки
Видно что ООП языки — примерно одинаковой компактности, в то время как язык без ООП даже на простейшем примере потребовал писать почти в 2 раза больше строк кода. Хотя там еще добавляется многословность в связи с Option — но кто им виноват, что не использовали ? как в C# на уровне языка, а то постоянно лепят свой Option.
Выводы какие? Даже на простейшем примере видно удобство ООП. А теперь представьте что пример будет реальным — сразу 50 тыс. строк превращаются в 100 тыс.