23

I'm hoping to get some tips to kinda help me break out of what i consider after all these years a bad habit of procedural programming. Every time i attempt to do a project in OOP i end up eventually reverting to procedural. I guess i'm not completely convinced with OOP (even though i think i've heard everything good about it!).

So i guess any good practical examples of common programming tasks that i often carry out such as user authentication/management, data parsing, CMS/Blogging/eComs are the kinda of things i do often, yet i haven't been able to get my head around how to do them in OOP and away from procedural, especially as the systems i build tend to work and work well.

One thing i can see as a downfall to my development, is that i do reuse my code often, and it often needs more rewrites and improvement, but i sometimes consider this as a natural evolution of my software development.

Yet i want to change! to my fellow programmers, help :) any tips on how i can break out of this nasty habbit?

4

20 に答える 20

19

オブジェクト指向プログラミングを使用する正当な理由や動機が見つからない場合、それを使用する意味は何ですか?

あなたは、アイデアをオブジェクトとして考え、操作する必要性に動機付けられなければなりません。オブジェクトではなく、概念、フロー、または機能を認識する必要があると感じ、概念、アイデア、または機能フローに向けられたプログラミングに動機付けられる人々がいます。

13年ほど前、必要なアイデアがあったからといってcからc ++に切り替えましたが、cは簡単には実行できませんでした。要するに、私の必要性は、オブジェクトに向けられた私のプログラミングを動機づけました。

オブジェクト指向の考え方

まず、バイト、文字、整数、浮動小数点数があります。

次に、プログラムはローカルおよび静的のすべての種類の変数で乱雑になり始めます。次に、一般的に渡されるすべての変数を理解したので、それらを構造体にグループ化することにしました。

データの集合体

したがって、printerの情報のように、すべての変数をPrinter構造体に含める必要があります。

{id, name, location,
 impactType(laser|inkjet|ribbon),
  manufacturer, networkAddr},
  etc.

そのため、プリンター情報に対して関数の後に関数を呼び出すと、引数のリストが長い関数や、クロストークの可能性が非常に高い静的変数の大規模なコレクションがなくなります。

情報の取り込み

しかし、データの集合体は十分ではありません。私はまだデータを処理するためにたくさんの関数に依存する必要があります。したがって、私は賢明なアイデアを持っていたか、関数ポインタをPrinter構造体に組み込んでいました。

{id, name, location,
 impactType(laser|inkjet|ribbon),
 manufacturer, networkAddr,
 *print(struct printer),
 *clean(struct printer)
}

データにデータの処理/認識方法に関するプロセスが含まれている場合、データは情報に段階的に移行します。

情報の量子化

現在、レーザー、リボン、およびインクジェットプリンターはすべて同じ情報のセットを持っているわけではありませんが、それらはすべて情報の中で最も一般的な分母(LCD)のセットを持っています。

すべてのプリンタに共通の情報:ID、名前、場所など

リボンプリンターでのみ検出される情報:usedCycles、ribbon(fabric | cellophane)、colourBandsなど

インクジェットでのみ見られる情報:インクカートリッジなど

レーザーでのみ見つかった情報:..。

私と多くのオブジェクト指向コホートでは、プリンターの種類ごとに個別の構造体/カプセル化を定義するのではなく、すべての共通情報を1つの共通情報カプセル化に量子化することを好みます。

次に、すべてのプリンターが同じ方法で印刷またはクリーニングされるわけではないため、各タイプのプリンターを参照するすべての関数を管理するフレームワークを使用することをお勧めします。

それで、オブジェクトから離れた方向に向けられたあなたの好み/動機は、あなたがオブジェクトを使わない方があなたのプログラミング生活がより簡単であるとあなたに言っていますか?これらすべての構造的な複雑さを自分で管理することを好むこと。あなたはそのように感じるのに十分なソフトウェアを書いていなかったに違いありません。

怠惰の必要性

一部の人々は言う-必要性は創造性の母です。(そして、お金の愛は悪の根源です)。

しかし、私と私のコホートにとって、必要性に直面した怠惰は創造性の親です。(そしてお金の不足は悪のもう一つの親です)。

したがって、最短経路の原則があなたの人生に浸透し、オブジェクトを使ったプログラミングに向けて卒業する以外に選択肢がないように、プログラミングに対して怠惰な態度をとることをお勧めします。

于 2009-12-09T00:25:37.323 に答える
15

Step 1. Read a good Design Patterns book. http://www.oodesign.com/

Step 2. Pick something you already know and rework it from an OO perspective. This is the Code Dojo approach. Take a problem that you already understand, and define the object classes.

I did this -- and wrote down what I did.

See http://homepage.mac.com/s_lott/books/oodesign.html#book-oodesign

You can do the same series of exercises to get the hang of OO design and code.

于 2009-12-08T22:10:23.833 に答える
5

The OO mindset is based on principles that lie at a much more basic level than design patterns. Design patterns are somehow fashionable these days (and have been for a while), and they are useful, but they are just one more layer that you can put upon more basic stuff that you absolutely must learn and master if you want to do OO properly. In other words: you can do OO perfectly without design patterns. In fact, many of us did OO well before the phrase "design patterns" was even coined.

Now, there is stuff you can't do without. I suggest you start at the basics. Read and understand "Object-Oriented Software Construction" 2nd edition by Bertrand Meyer. It's probably the best book on OO programming around, both in width and depth. That is if you're interested in programming.

于 2009-12-08T22:40:44.820 に答える
4

まず、何か新しいことを学ぶためのステップを踏んでおめでとうございます!開発者がテクノロジーとともに進化しないことを決定したとき、私はそれを嫌います。

手続き型プログラミングからOOPに移行する限り、あなたができることの1つは、既存のアプリを使用することです(他の人が述べているように)。テキストエディターを開く前に、座って、アプリケーションは変換されます。私は、オブジェクト指向プログラミングの半分以上が最初にあなたの心の中で概念的なオブジェクトを定義していることを発見しました。

繰り返しになりますが、デザインパターンに関するすべての人の推奨事項に同意します。具体的には、MVC(Model-View-Controller)パターンを調べます。これは、最も理解しやすいパターンである可能性があるためです。すでにコードを記述しているので、既存のアプリケーションを確認して、各部分をM、V、またはCのカテゴリーに分類し始めることができるはずです。

頑張って楽しんでください!

于 2009-12-08T22:20:09.280 に答える
4

There are already quite a few answers about where to find information on programming in an object-oriented fashion. Indeed, there are many great books out there that will define the basic concepts however I think the question was more on how to "stick with it" through development for someone new to the method.

Of the many concepts in object-oriented programming, the main one that will keep you on track as a newcomer is encapsulation. Does my class know how to take care of itself? Does my class have behaviour? If it doesn't, then you don't have a class, you have a structure and you'll likely be writing a lot of procedures to change its state (as it's said, "you are back to writing C in Java"). Does my class only expose methods publicly that are required for its use? Those questions may not be terribly elaborated upon but perhaps consider this thought experiment when designing your classes: What if each one of your application's classes were to be developed and maintained by a different developer on the internet and the classes also had to interact with eachother over the internet. Would each developer agree that the class they are writing and maintaining adheres to the single responsibility principle and therefore be happy that they aren't maintaining what should be someone elses code?

Regarding the design of class interfaces, consider writing all of the code that uses your classes first. Don't worry about what has to happen at the metal yet. You should be able to stub out the entire program in terms of the class relationships before you write your first bit-twiddling implementation detail. If you can't do this without twiddling bits or making a variable public, then it is time to go back to your class relationship diagram and see if you are missing an abstraction. Phrased another way, use your code before you write your code. Do this first, and you might be suprised how clean your code and interfaces turn out if you've never done it before.

While design patterns are certainly good to learn, and some are extremely powerful, they aren't generally intrinsically object-oriented and as some argue (and I tend to agree) design patterns are often just exposed weaknesses in the language. One language's design patterns is another's basic founding principles. So when starting, don't get hung up on whether or not some relationship is a good candidate for a bridge or a facade; this is not specific to object-oriented thought, this is related to what a specific language's constructs afford.

于 2009-12-09T02:04:39.193 に答える
3

Don't.

First, learn writing. Second, learn user experience and interaction design. Third, learn business analysis. Fourth, learn role modeling.

Now that you know what objects are, you will come to see that objects are not found in code. They are found at runtime; in the space between the machine and the user's mind. This is what object orientation really means. Unfortunately recent academia has twisted it into an engineering concept. Nothing could be further off the mark. And try as they might to emulate, the end result is crap. Why? Because the "OOP" paradigm as the industry knows it today is built on a fundamentally flawed idea: decompositional analysis of identity. How is this flawed? Because identity in and of itself is meaningless. It is void. In a mathematical sense, in a philosophical sense. This is not how a human being perceives and interacts with the world.

Canon: Alan Kay, Trygve Reenskaug, James (Jim) Coplien

How I wish I was in your position. :)

于 2011-01-14T21:07:36.953 に答える
2

OO設計にCRC(クラス/責任/コラボレーション)カードアプローチを使用することを検討するかもしれません。これはそれほど恐ろしいことではありません。オブジェクトがどうあるべきか、そしてどのオブジェクトがどのタスクを担当するかを整理する方法であり、考えを明確にするためにファイルカードの束に何かを書き留めます。

それはもともとOO思考のための教育ツールとして設計されており、あなたのために働くかもしれません。元の論文は次の場所にあります:http://c2.com/doc/oopsla89/paper.html

上記のポスターは、あなたをOOの習慣に強制するために、Smalltalkでプログラミングすることを提案しました。そして、それは良い提案です-Smalltalkは確かに私に多くの良いことをしましたが、

a)新しい言語を学ぶ暇がないかもしれません。もしそうなら、素晴らしい。

b)私はSmalltalkを使用してオブジェクト指向プログラミングの大学のコースを指導していました。学生たちは「FORTRANをどの言語でも書くことができる」という古いジョークを証明する素晴らしい仕事をしました。

最後に、私がOOについて(本から)学んでいたとき、あなたが多くのサブクラスを作成し、複雑なクラス階層を作成しているという印象を受けました。OOプログラマーと仕事を始めたとき、思ったほど頻繁には起こらなかったことに気づきました。みんなが学んでいるときにこの間違いを犯していると思います。

于 2009-12-09T00:59:24.213 に答える
2

I think it helps to first skim over some existing, decent, proven object-oriented code (e.g. Qt source code) so you can get a feel for "how it's done". After that, learning from a book or creating your own framework will be much more effective.

In general, it really helps to see things in context before reading about and practicing them, as it gives you moments to say to yourself, "Oh, that's why they did that!" At least that's how it works for me.

于 2009-12-08T22:17:56.303 に答える
2

The hard part of OO is which stuff should be put together into one object. As you already mentioned the evolution of your source code, here you have a simple guideline on how to evolve your source code towards an OO design:

"Put stuff together that changes together."

When two pieces of code have similar change velocities, that's a hint that they should be placed in the same object. When the change velocities are different, consider placing them in different objects.

This is also known as "Change Velocity".

If you follow that guideline your code will naturally evolve towards a good OO design. Why?

Fragments of code often have similar change velocities if they access a common representation. Every time the representation changes, all the pieces of code that use it must change at once. This is part of the reason we use objects as modules to encapsulate representation. Separating interface from implementation makes sense under this guideline too - the implementation changing more often and thus having a higher change velocity.

If a class has a stable part and an unstable part, that's a difference in change velocity that suggests moving the stable part to a (possibly abstract) base class.

Similarly, if a class has two parts which change equally often but at different times or in different directions (that is to say, for different reasons), then that again suggests refactoring the class.

Sometimes replace "class" with "method". For example, if one line of a method is likely to change more often than the rest - perhaps it is the line which creates a new object instance and contains the name of its class - consider moving it to its own routine. Then subclasses can easily effect their change by overriding it.

I came across this concept on C2 wiki many years ago, but I've rarely seen it used since. I find it very useful. It expresses some crucial underlying motivation of object oriented design. Of course, it's therefore blindingly obvious.

These are changes of the program. There is another sense of change velocity - you don't want instance variables changing at different rate, or rather that is a sign of potential problems. For example, in a graphics editor you shouldn't keep the figures and the handles in the same collection, because the figures change once a minute or once an hour and the handles change once a second or once a minute.

In a somewhat larger view, you want a system to be able to change fast enough to keep up with the changes in the business.

PS: the other principle that you should follow is "Law of Demeter", that is, an object should only talk to its friends. Friends are: yourself, instance variables, parameters, locals, and members of friendly collections - but not globals and static variables.

于 2009-12-09T03:07:42.223 に答える
1

より良いコードを書く唯一の方法は、より多くのコードを書くことです。手続き的に実装したプロジェクトを取得し、それをOOPに変換します(両方をサポートする言語で作業していると仮定します)。おそらく、最初は壊れやすく、緊密に結合されたソリューションになってしまうでしょうが、それは問題ありません。悪いOOP実装を取り、それをより良いものにリファクタリングし始めます。最終的には、何が機能し、何が機能しないかがわかります。

次のステップに進む準備ができたら、デザインパターンの本を手に取って、OOPデザイン用語のいくつかを学びましょう。これは厳密には必要ではありませんが、一般的な問題と解決策のいくつかをよりよく理解することができます。

于 2009-12-08T22:23:47.400 に答える
1

I think you should convince yourself by researching all of the downsides with procedural programming, for example (some buzzwords following, watch out): scope, state ... practically you'd be able to extract many terms just by reading examples of design patterns (read: common examples of using objects together.)

Stressing yourself into learning something you don't believe in won't get you anywhere. Start being really critical on your earlier work and refactor it to avoid copied code and using the global scope, and you'll find yourself wanting more.

于 2009-12-08T22:36:56.450 に答える
1

For me the ah-ha moment of OOP was the first time I looked at code and realised I could refactor common stuff into a base class. You clearly know your way around code and re-use, but you need to think around classes not procedures. With user authentication it's clear you're going to have a username and password, now they go into the base class, but what if you need a tokenId as well, re-use your existing login base class, and create a new subclass from that with the new behaviour, all your existing code works without change.

See how that works for you.

于 2009-12-09T00:10:10.050 に答える
1

Well, first off design patterns are about the worst thing to pattern your programming to.

It's just a big set of things. It's nothing to do with OOP, and most of them such as singleton are constantly used for all the wrong reasons (ie initialization). Some of these things you have to use so telling you about them is pointless, others are counterproductive, and the rest are just special case things. If you try to learn anything this way everything will start to look like some bizarre doodad someone came up with for a very special problem or because they needed infinite genericity (which is seldom true). Don't let people con you into using a million iterators and templates for no reason and make things ten times more complicated.

Really OOP is a simple subject that gets massively overcomplicated. Unfortunately in C++ it has a lot of issues but really simple virtual methods are what matters. Pure virtual base classes used much like a java interface object are the most useful but also just plain virtual methods here and there will come in handy.

It's mostly been overblown. It also doesn't lend itself well to every problem. If you make database and gui stuff it lends itself well to that. If you make system tools it is usually not as helpful.

于 2009-12-09T01:25:41.587 に答える
1

I found that one of the things which has really helped solidify the benefits of OOP for me has been writing unit tests with a mock object framework (such as EasyMock). Once you start to develop that way, you can see how classes help you isolate modules behind interfaces and also allow for easier testing.

One thing to keep in mind is that when people are first learning OOP, often there is an overemphasis on inheritance. Inheritance has its place, but it's a tool that can easily be overused. Composition or simple interface implementation are often better ways of doing things. Don't go so far in attempting to reuse code via inheritance that you make inheritance trees which make little sense from a polymorphism standpoint. The substitution principle is what makes inheritance/interface implementation powerful, not the fact that you can reuse code by subclassing.

于 2009-12-09T07:19:02.020 に答える
0

I have found that a very intense way learning to train abstraction in programming is to build a OOP library with a defined functionality, and then to implement two projects with similar but still different requirements that are building on that library, at the same time.

This is very time-consuming and you need to have learned the basics of OOP first (S.Lott has some great links in the other answer). Constant refactoring and lots of "Doh!" moments are the rule; but I found this a great way to learn modular programming because everything I did was immediately noticeable in the implementation of one of the projects.

于 2009-12-08T22:08:43.293 に答える
0

A great step would be to start of with a OOP framework, you can still write procedural code in the framework but over time you can refine your coding habits & start converting functionality into objects.

Also reading about patterns & data modeling will give you more ideas about to code your logic in a OOP style.

于 2009-12-08T22:11:21.790 に答える
0

Simply practice. If you've read everything about OOP and you know something about OOP and you know the OOP principals implemented in your language PHP... then just practice, practice and practice some more.

Now, don't go viewing OOP as the hammer and everything else as the nail, but do try to incorporate at least one class in a project. Then see if you can reuse it in another project etc..

于 2009-12-08T22:32:06.327 に答える
0

Learn a new language, one that helps to move you gently to OOP. Java is nice, but a bit bloated, though. But its system library is mainly OO, so you are force to use objects. Moving to another language also helps you not to reuse your old code :-)

于 2009-12-08T22:40:35.487 に答える
0

I think it´s important to learn the theory first. So reading a book would be a good start.

于 2009-12-08T22:50:51.850 に答える
0
  1. I believe that the mechanics of OOP seem completely arbitrary and make no sense until you read a book on design patterns and understand the "why" of it. I recommend Head First Design Patterns. I thought OOP was ridiculous and completely useless until I picked up this book and saw what it was actually good for.

  2. OO makes a lot more sense when you understand function pointers and how it relates to indirect function calls and late binding. Play around with function pointers in C, C++, or D for a little while and get a feel for what they're for and how they work. The polymorphism/virtual function part of OO is just another layer of abstraction on top of this.

  3. Procedural is the right tool for some jobs. Don't act like it's wrong. IMHO all three major paradigms (procedural, OO, functional) are valuable even at a fine-grained level, within a single module. I tend to prefer:

Procedural is good when my problem is simple (or I've already factored it enough with functional and OO that I now have a subproblem that I consider simple) and I want the most straightforward solution without a lot of abstraction getting in the way.

Object-oriented is good when my problem is more complex and has lots of state that makes sense in the context of the problem domain. In these cases the existence of state is not an implementation detail, but the exact representation is one that I prefer to abstract away.

Functional is good when my problem is complex but has no state that makes sense at the level of the problem domain. From the perspective of the problem domain, the existence of state is an implementation detail.

于 2009-12-09T00:53:37.797 に答える